Comparing version 3.6.0 to 3.7.0
# crypto-ld ChangeLog | ||
## 3.7.0 - TBD | ||
### Added | ||
- Add support for Node 12 Ed25519 generate, sign, and verify. | ||
- Make `sodium-native` an optional dependency. | ||
## 3.6.0 - 2019-08-06 | ||
@@ -4,0 +10,0 @@ |
@@ -81,2 +81,62 @@ /*! | ||
static async generate(options = {}) { | ||
if(env.nodejs && require('semver').gte(process.version, '12.0.0')) { | ||
const bs58 = require('bs58'); | ||
const { | ||
asn1, ed25519: {privateKeyFromAsn1, publicKeyFromAsn1}, | ||
util: {ByteBuffer} | ||
} = forge; | ||
const {promisify} = require('util'); | ||
const {createPublicKey, generateKeyPair} = require('crypto'); | ||
const publicKeyEncoding = {format: 'der', type: 'spki'}; | ||
const privateKeyEncoding = {format: 'der', type: 'pkcs8'}; | ||
// if no seed provided, generate a random key | ||
if(!('seed' in options)) { | ||
const generateKeyPairAsync = promisify(generateKeyPair); | ||
const {publicKey, privateKey} = await generateKeyPairAsync('ed25519', { | ||
publicKeyEncoding, privateKeyEncoding | ||
}); | ||
const publicKeyBytes = publicKeyFromAsn1( | ||
asn1.fromDer(new ByteBuffer(publicKey))); | ||
const {privateKeyBytes} = privateKeyFromAsn1( | ||
asn1.fromDer(new ByteBuffer(privateKey))); | ||
return new Ed25519KeyPair({ | ||
publicKeyBase58: bs58.encode(publicKeyBytes), | ||
// private key is the 32 byte private key + 32 byte public key | ||
privateKeyBase58: bs58.encode(Buffer.concat( | ||
[privateKeyBytes, publicKeyBytes])), | ||
...options | ||
}); | ||
} | ||
// create a key from the provided seed | ||
const {seed} = options; | ||
let seedBytes; | ||
if(seed instanceof Uint8Array || Buffer.isBuffer(seed)) { | ||
seedBytes = Buffer.from(seed); | ||
} | ||
if(!(Buffer.isBuffer(seedBytes) && seedBytes.length === 32)) { | ||
throw new TypeError('`seed` must be a 32 byte Buffer or Uint8Array.'); | ||
} | ||
const _privateKey = require('./ed25519PrivateKeyNode12'); | ||
// create a node private key | ||
const privateKey = _privateKey.create({seedBytes}); | ||
// create a node public key from the private key | ||
const publicKey = createPublicKey(privateKey); | ||
// export the keys and extract key bytes from the exported DERs | ||
const publicKeyBytes = publicKeyFromAsn1( | ||
asn1.fromDer(new ByteBuffer(publicKey.export(publicKeyEncoding)))); | ||
const {privateKeyBytes} = privateKeyFromAsn1( | ||
asn1.fromDer(new ByteBuffer(privateKey.export(privateKeyEncoding)))); | ||
return new Ed25519KeyPair({ | ||
publicKeyBase58: bs58.encode(publicKeyBytes), | ||
// private key is the 32 byte private key + 32 byte public key | ||
privateKeyBase58: bs58.encode(Buffer.concat( | ||
[privateKeyBytes, publicKeyBytes])), | ||
...options | ||
}); | ||
} | ||
if(env.nodejs) { | ||
@@ -394,2 +454,24 @@ // TODO: use native node crypto api once it's available | ||
if(env.nodejs && require('semver').gte(process.version, '12.0.0')) { | ||
const bs58 = require('bs58'); | ||
const privateKeyBytes = util.base58Decode({ | ||
decode: bs58.decode, | ||
keyMaterial: key.privateKeyBase58, | ||
type: 'private' | ||
}); | ||
const _privateKey = require('./ed25519PrivateKeyNode12'); | ||
// create a Node private key | ||
const privateKey = _privateKey.create({privateKeyBytes}); | ||
const {sign} = require('crypto'); | ||
return { | ||
async sign({data}) { | ||
const signature = sign( | ||
null, Buffer.from(data.buffer, data.byteOffset, data.length), | ||
privateKey); | ||
return signature; | ||
} | ||
}; | ||
} | ||
if(env.nodejs) { | ||
@@ -442,2 +524,21 @@ const sodium = require('sodium-native'); | ||
function ed25519VerifierFactory(key) { | ||
if(env.nodejs && require('semver').gte(process.version, '12.0.0')) { | ||
const bs58 = require('bs58'); | ||
const publicKeyBytes = util.base58Decode({ | ||
decode: bs58.decode, | ||
keyMaterial: key.publicKeyBase58, | ||
type: 'public' | ||
}); | ||
const _publicKey = require('./ed25519PublicKeyNode12'); | ||
// create a Node public key | ||
const publicKey = _publicKey.create({publicKeyBytes}); | ||
const {verify} = require('crypto'); | ||
return { | ||
async verify({data, signature}) { | ||
return verify( | ||
null, Buffer.from(data.buffer, data.byteOffset, data.length), | ||
publicKey, signature); | ||
} | ||
}; | ||
} | ||
if(env.nodejs) { | ||
@@ -444,0 +545,0 @@ const sodium = require('sodium-native'); |
@@ -6,2 +6,4 @@ /* | ||
const {asn1, oids, util: {ByteBuffer}} = require('node-forge'); | ||
/** | ||
@@ -42,1 +44,88 @@ * Wraps Base58 decoding operations in | ||
}; | ||
exports.privateKeyDerEncode = ({privateKeyBytes, seedBytes}) => { | ||
if(!(privateKeyBytes || seedBytes)) { | ||
throw new TypeError('`privateKeyBytes` or `seedBytes` is required.'); | ||
} | ||
if(!privateKeyBytes && !(Buffer.isBuffer(seedBytes) && | ||
seedBytes.length === 32)) { | ||
throw new TypeError('`seedBytes` must be a 32 byte Buffer.'); | ||
} | ||
if(!seedBytes && !(Buffer.isBuffer(privateKeyBytes) && | ||
privateKeyBytes.length === 64)) { | ||
throw new TypeError('`privateKeyBytes` must be a 64 byte Buffer.'); | ||
} | ||
let p; | ||
if(seedBytes) { | ||
p = seedBytes; | ||
} else { | ||
// extract the first 32 bytes of the 64 byte private key representation | ||
p = Buffer.from(privateKeyBytes.buffer, privateKeyBytes.byteOffset, 32); | ||
} | ||
const keyBuffer = new ByteBuffer(p); | ||
const asn1Key = asn1.create( | ||
asn1.UNIVERSAL, | ||
asn1.Type.OCTETSTRING, | ||
false, | ||
keyBuffer.getBytes() | ||
); | ||
const a = asn1.create( | ||
asn1.Class.UNIVERSAL, | ||
asn1.Type.SEQUENCE, | ||
true, [ | ||
asn1.create( | ||
asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, | ||
asn1.integerToDer(0).getBytes()), | ||
// privateKeyAlgorithm | ||
asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ | ||
asn1.create( | ||
asn1.Class.UNIVERSAL, | ||
asn1.Type.OID, | ||
false, | ||
asn1.oidToDer(oids.EdDSA25519).getBytes() | ||
), | ||
]), | ||
// private key | ||
asn1.create( | ||
asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, | ||
asn1.toDer(asn1Key).getBytes()), | ||
] | ||
); | ||
const privateKeyDer = asn1.toDer(a); | ||
return Buffer.from(privateKeyDer.getBytes(), 'binary'); | ||
}; | ||
exports.publicKeyDerEncode = ({publicKeyBytes}) => { | ||
if(!(Buffer.isBuffer(publicKeyBytes) && publicKeyBytes.length === 32)) { | ||
throw new TypeError('`publicKeyBytes` must be a 32 byte Buffer.'); | ||
} | ||
// add a zero byte to the front of the publicKeyBytes, this results in | ||
// the bitstring being 256 bits vs. 170 bits (without padding) | ||
const zeroBuffer = Buffer.from(new Uint8Array([0])); | ||
const keyBuffer = new ByteBuffer(Buffer.concat([zeroBuffer, publicKeyBytes])); | ||
const a = asn1.create( | ||
asn1.Class.UNIVERSAL, | ||
asn1.Type.SEQUENCE, | ||
true, [ | ||
asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ | ||
asn1.create( | ||
asn1.Class.UNIVERSAL, | ||
asn1.Type.OID, | ||
false, | ||
asn1.oidToDer(oids.EdDSA25519).getBytes() | ||
), | ||
]), | ||
// public key | ||
asn1.create( | ||
asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, | ||
keyBuffer.getBytes()), | ||
] | ||
); | ||
const publicKeyDer = asn1.toDer(a); | ||
return Buffer.from(publicKeyDer.getBytes(), 'binary'); | ||
}; |
{ | ||
"name": "crypto-ld", | ||
"version": "3.6.0", | ||
"version": "3.7.0", | ||
"description": "A library for managing cryptographic keys using Linked Data.", | ||
@@ -27,3 +27,6 @@ "homepage": "https://github.com/digitalbazaar/crypto-ld", | ||
"bs58": "^4.0.1", | ||
"node-forge": "^0.8.0", | ||
"node-forge": "~0.9.0", | ||
"semver": "^6.2.0" | ||
}, | ||
"optionalDependencies": { | ||
"sodium-native": "^2.3.0" | ||
@@ -79,3 +82,6 @@ }, | ||
"sodium-native": false, | ||
"util": false | ||
"util": false, | ||
"semver": false, | ||
"./lib/ed25519PublicKeyNode12.js": false, | ||
"./lib/ed25519PrivateKeyNode12.js": false | ||
}, | ||
@@ -82,0 +88,0 @@ "engines": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
54930
12
1346
5
+ Addedsemver@^6.2.0
+ Addednode-forge@0.9.2(transitive)
+ Addedsemver@6.3.1(transitive)
- Removedsodium-native@^2.3.0
- Removednode-forge@0.8.5(transitive)
Updatednode-forge@~0.9.0