Skip to content
This repository has been archived by the owner on Jul 21, 2023. It is now read-only.

Commit

Permalink
fix: go ed25519 interop
Browse files Browse the repository at this point in the history
fixes #175
  • Loading branch information
jacobheun committed Jul 20, 2020
1 parent 4aa77a6 commit 2f18a07
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 34 deletions.
20 changes: 13 additions & 7 deletions src/keys/ed25519-class.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,17 @@ class Ed25519PrivateKey {
}

function unmarshalEd25519PrivateKey (bytes) {
bytes = ensureKey(bytes, crypto.privateKeyLength + crypto.publicKeyLength)
// Try the old, redundant public key version
if (bytes.length > crypto.privateKeyLength) {
bytes = ensureKey(bytes, crypto.privateKeyLength + crypto.publicKeyLength)
const privateKeyBytes = bytes.slice(0, crypto.privateKeyLength)
const publicKeyBytes = bytes.slice(crypto.privateKeyLength, bytes.length)
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes)
}

bytes = ensureKey(bytes, crypto.privateKeyLength)
const privateKeyBytes = bytes.slice(0, crypto.privateKeyLength)
const publicKeyBytes = bytes.slice(crypto.privateKeyLength, bytes.length)
const publicKeyBytes = bytes.slice(crypto.publicKeyLength)
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes)
}

Expand All @@ -111,11 +119,9 @@ async function generateKeyPairFromSeed (seed) {
}

function ensureKey (key, length) {
if (Buffer.isBuffer(key)) {
key = new Uint8Array(key)
}
if (!(key instanceof Uint8Array) || key.length !== length) {
throw errcode(new Error('Key must be a Uint8Array or Buffer of length ' + length), 'ERR_INVALID_KEY_TYPE')
key = Uint8Array.from(key || [])
if (key.length !== length) {
throw errcode(new Error(`Key must be a Uint8Array or Buffer of length ${length}, got ${key.length}`), 'ERR_INVALID_KEY_TYPE')
}
return key
}
Expand Down
46 changes: 30 additions & 16 deletions test/fixtures/go-key-ed25519.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,42 @@
const { Buffer } = require('buffer')

module.exports = {
// These were generated in a gore (https://github.com/motemen/gore) repl session:
// Generation code from https://github.com/libp2p/js-libp2p-crypto/issues/175#issuecomment-634467463
//
// :import github.com/libp2p/go-libp2p-crypto
// :import crypto/rand
// priv, pub, err := crypto.GenerateEd25519Key(rand.Reader)
// pubkeyBytes, err := pub.Bytes()
// privkeyBytes, err := priv.Bytes()
// data := []byte("hello! and welcome to some awesome crypto primitives")
// sig, err := priv.Sign(data)
// package main
//
// :import io/ioutil
// ioutil.WriteFile("/tmp/pubkey_go.bin", pubkeyBytes, 0644)
// // etc..
//
// Then loaded into a node repl and dumped to arrays with:
// import (
// "crypto/rand"
// "fmt"
// "strings"

// "github.com/libp2p/go-libp2p-core/crypto"
// )

// func main() {
// priv, pub, _ := crypto.GenerateEd25519Key(rand.Reader)
// pubkeyBytes, _ := pub.Bytes()
// privkeyBytes, _ := priv.Bytes()
// data := []byte("hello! and welcome to some awesome crypto primitives")
// sig, _ := priv.Sign(data)
// fmt.Println("{\n publicKey: Buffer.from(", strings.Replace(fmt.Sprint(pubkeyBytes), " ", ",", -1), "),")
// fmt.Println(" privateKey: Buffer.from(", strings.Replace(fmt.Sprint(privkeyBytes), " ", ",", -1), "),")
// fmt.Println(" data: Buffer.from(", strings.Replace(fmt.Sprint(data), " ", ",", -1), "),")
// fmt.Println(" signature: Buffer.from(", strings.Replace(fmt.Sprint(sig), " ", ",", -1), ")\n}")
// }
//
// var pubkey = Array.from(fs.readFileSync('/tmp/pubkey_go.bin'))
// console.log(JSON.stringify(pubkey))
verify: {

// The legacy key unnecessarily appends the publickey. (It's already included) See https://github.com/libp2p/js-libp2p-crypto/issues/175
redundantPubKey: {
privateKey: Buffer.from([8, 1, 18, 96, 201, 208, 1, 110, 176, 16, 230, 37, 66, 184, 149, 252, 78, 56, 206, 136, 2, 38, 118, 152, 226, 197, 117, 200, 54, 189, 156, 218, 184, 7, 118, 57, 233, 49, 221, 97, 164, 158, 241, 129, 73, 166, 225, 255, 193, 118, 22, 84, 55, 15, 249, 168, 225, 180, 198, 191, 14, 75, 187, 243, 150, 91, 232, 37, 233, 49, 221, 97, 164, 158, 241, 129, 73, 166, 225, 255, 193, 118, 22, 84, 55, 15, 249, 168, 225, 180, 198, 191, 14, 75, 187, 243, 150, 91, 232, 37]),
publicKey: Buffer.from([8, 1, 18, 32, 233, 49, 221, 97, 164, 158, 241, 129, 73, 166, 225, 255, 193, 118, 22, 84, 55, 15, 249, 168, 225, 180, 198, 191, 14, 75, 187, 243, 150, 91, 232, 37]),
data: Buffer.from([104, 101, 108, 108, 111, 33, 32, 97, 110, 100, 32, 119, 101, 108, 99, 111, 109, 101, 32, 116, 111, 32, 115, 111, 109, 101, 32, 97, 119, 101, 115, 111, 109, 101, 32, 99, 114, 121, 112, 116, 111, 32, 112, 114, 105, 109, 105, 116, 105, 118, 101, 115]),
signature: Buffer.from([7, 230, 175, 164, 228, 58, 78, 208, 62, 243, 73, 142, 83, 195, 176, 217, 166, 62, 41, 165, 168, 164, 75, 179, 163, 86, 102, 32, 18, 84, 150, 237, 39, 207, 213, 20, 134, 237, 50, 41, 176, 183, 229, 133, 38, 255, 42, 228, 68, 186, 100, 14, 175, 156, 243, 118, 125, 125, 120, 212, 124, 103, 252, 12])
},
verify: {
publicKey: Buffer.from( [8,1,18,32,163,176,195,47,254,208,49,5,192,102,32,63,58,202,171,153,146,164,25,212,25,91,146,26,117,165,148,6,207,90,217,126] ),
privateKey: Buffer.from( [8,1,18,64,232,56,175,20,240,160,19,47,92,88,115,221,164,13,36,162,158,136,247,31,29,231,76,143,12,91,193,4,88,33,67,23,163,176,195,47,254,208,49,5,192,102,32,63,58,202,171,153,146,164,25,212,25,91,146,26,117,165,148,6,207,90,217,126] ),
data: Buffer.from( [104,101,108,108,111,33,32,97,110,100,32,119,101,108,99,111,109,101,32,116,111,32,115,111,109,101,32,97,119,101,115,111,109,101,32,99,114,121,112,116,111,32,112,114,105,109,105,116,105,118,101,115] ),
signature: Buffer.from( [160,125,30,62,213,189,239,92,87,76,205,169,251,149,187,57,96,85,175,213,22,132,229,60,196,18,117,194,12,174,135,31,39,168,174,103,78,55,37,222,37,172,222,239,153,63,197,152,67,167,191,215,161,212,216,163,81,77,45,228,151,79,101,1] )
}
}
25 changes: 14 additions & 11 deletions test/keys/ed25519.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,25 +131,28 @@ describe('ed25519', function () {

describe('go interop', () => {
// @ts-check
/**
* @type {PrivateKey}
*/
let privateKey

before(async () => {
const key = await crypto.keys.unmarshalPrivateKey(fixtures.verify.privateKey)
privateKey = key
})

it('verifies with data from go', async () => {
const key = crypto.keys.unmarshalPublicKey(fixtures.verify.publicKey)
const ok = await key.verify(fixtures.verify.data, fixtures.verify.signature)
expect(ok).to.eql(true)
})

it('verifies with data from go with redundant public key', async () => {
const key = crypto.keys.unmarshalPublicKey(fixtures.redundantPubKey.publicKey)
const ok = await key.verify(fixtures.redundantPubKey.data, fixtures.redundantPubKey.signature)
expect(ok).to.eql(true)
})

it('generates the same signature as go', async () => {
const sig = await privateKey.sign(fixtures.verify.data)
const key = await crypto.keys.unmarshalPrivateKey(fixtures.verify.privateKey)
const sig = await key.sign(fixtures.verify.data)
expect(sig).to.eql(fixtures.verify.signature)
})

it('generates the same signature as go with redundant public key', async () => {
const key = await crypto.keys.unmarshalPrivateKey(fixtures.redundantPubKey.privateKey)
const sig = await key.sign(fixtures.redundantPubKey.data)
expect(sig).to.eql(fixtures.redundantPubKey.signature)
})
})
})

0 comments on commit 2f18a07

Please sign in to comment.