Skip to content

Commit

Permalink
refactor: pass one tweak object
Browse files Browse the repository at this point in the history
  • Loading branch information
feri42 committed Apr 24, 2024
1 parent 1e6c10c commit 0ae7d57
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 27 deletions.
16 changes: 10 additions & 6 deletions features/keychain/module/__tests__/schnorr.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ describe('Schnorr signer', () => {
const secp256k1Signer = create({ getPrivateHDKey })

const publicKey = await secp256k1Signer.getPublicKey({})
const tweakHash = tapTweakHash(publicKey)
const scalar = tapTweakHash(publicKey)

const result = await secp256k1Signer.signSchnorr({
data: Buffer.from(fixture.buffer, 'hex'),
tweak: true,
tweakOptions: { extraEntropy: Buffer.from(fixture.entropy, 'hex'), tweakHash },
tweak: {
scalar,
options: { extraEntropy: Buffer.from(fixture.entropy, 'hex') },
},
})

expect(Buffer.from(result).toString('hex')).toBe(fixture.sig)
Expand All @@ -53,13 +55,15 @@ describe('Schnorr signer', () => {
const secp256k1Signer = create({ getPrivateHDKey })

const publicKey = await secp256k1Signer.getPublicKey({})
const tweakHash = tapTweakHash(publicKey)
const scalar = tapTweakHash(publicKey)

expect(publicKey.toString('hex')).toBe(fixture.pub)

const tweakedPublicKey = await secp256k1Signer.getPublicKey({
tweak: true,
tweakOptions: { extraEntropy: Buffer.from(fixture.entropy, 'hex'), tweakHash },
tweak: {
scalar,
options: { extraEntropy: Buffer.from(fixture.entropy, 'hex') },
},
})
expect(tweakedPublicKey.toString('hex')).toBe(fixture.pub2)
}
Expand Down
20 changes: 10 additions & 10 deletions features/keychain/module/crypto/secp256k1.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { tweakPrivateKey, tweakPublicKey } from './tweak'
const isValidEcOptions = (ecOptions) =>
!ecOptions || Object.keys(ecOptions).every((key) => ['canonical'].includes(key))

const isValidTweakOptions = (tweakOptions) =>
!tweakOptions ||
Object.keys(tweakOptions).every((key) => ['tweakHash', 'extraEntropy'].includes(key))
const isValidTweak = (tweak) =>
!tweak ||
(tweak.scalar && Object.keys(tweak.options || {}).every((key) => ['extraEntropy'].includes(key)))

export const create = ({ getPrivateHDKey }) => {
const EC = elliptic.ec
Expand All @@ -24,16 +24,16 @@ export const create = ({ getPrivateHDKey }) => {
const signature = curve.sign(data, privateKey, pick(ecOptions, ['canonical']))
return enc === 'der' ? Buffer.from(signature.toDER()) : { ...signature }
},
signSchnorr: async ({ seedId, keyId, data, tweak = false, tweakOptions }) => {
assert(isValidTweakOptions(tweakOptions), 'signSchnorr: invalid tweak options')
signSchnorr: async ({ seedId, keyId, data, tweak }) => {
assert(isValidTweak(tweak), 'signSchnorr: invalid tweak data')
const hdkey = getPrivateHDKey({ seedId, keyId })
const privateKey = tweak ? tweakPrivateKey({ hdkey, tweakOptions }) : hdkey.privateKey
return ecc.signSchnorr(data, privateKey, tweakOptions?.extraEntropy)
const privateKey = tweak ? tweakPrivateKey({ hdkey, scalar: tweak.scalar }) : hdkey.privateKey
return ecc.signSchnorr(data, privateKey, tweak?.options?.extraEntropy)
},
getPublicKey: async ({ seedId, keyId, tweak = false, tweakOptions }) => {
assert(isValidTweakOptions(tweakOptions), 'getPublicKey: invalid tweak options')
getPublicKey: async ({ seedId, keyId, tweak }) => {
assert(isValidTweak(tweak), 'getPublicKey: invalid tweak data')
const hdkey = getPrivateHDKey({ seedId, keyId })
return tweak ? tweakPublicKey({ hdkey, tweakOptions }) : hdkey.publicKey
return tweak ? tweakPublicKey({ hdkey, scalar: tweak.scalar }) : hdkey.publicKey
},
})

Expand Down
19 changes: 8 additions & 11 deletions features/keychain/module/crypto/tweak.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import assert from 'minimalistic-assert'
import ecc from '@exodus/bitcoinerlab-secp256k1'

export const tweakPrivateKey = ({ hdkey, tweakOptions = {} }) => {
const { publicKey } = hdkey
export const tweakPrivateKey = ({ hdkey, scalar }) => {
const { privateKey, publicKey } = hdkey
assert(ecc.isPrivate(privateKey), 'tweakPrivateKey: expected valid private key')
assert(ecc.isPointCompressed(publicKey), 'tweakPrivateKey: expected compressed public key')

const { tweakHash } = tweakOptions
assert(tweakHash, 'tweakPrivateKey: tweakHash is required')
let tweakedPrivateKey = publicKey[0] === 3 ? ecc.privateNegate(privateKey) : privateKey
tweakedPrivateKey = Buffer.from(ecc.privateAdd(tweakedPrivateKey, scalar))

let { privateKey } = hdkey
privateKey = publicKey[0] === 3 ? ecc.privateNegate(privateKey) : privateKey
privateKey = Buffer.from(ecc.privateAdd(privateKey, tweakHash))

return privateKey
return tweakedPrivateKey
}

export const tweakPublicKey = ({ hdkey, tweakOptions }) => {
const privateKey = tweakPrivateKey({ hdkey, tweakOptions })
export const tweakPublicKey = ({ hdkey, scalar }) => {
const privateKey = tweakPrivateKey({ hdkey, scalar })

return Buffer.from(ecc.pointFromScalar(privateKey, true))
}

0 comments on commit 0ae7d57

Please sign in to comment.