fix: secp256k1 instruction should accept 64 byte public key (#15584)
This commit is contained in:
parent
640e36287e
commit
55f357153a
|
@ -13,7 +13,7 @@ import {toBuffer} from './util/to-buffer';
|
||||||
const {publicKeyCreate, ecdsaSign} = secp256k1;
|
const {publicKeyCreate, ecdsaSign} = secp256k1;
|
||||||
|
|
||||||
const PRIVATE_KEY_BYTES = 32;
|
const PRIVATE_KEY_BYTES = 32;
|
||||||
const PUBLIC_KEY_BYTES = 65;
|
const PUBLIC_KEY_BYTES = 64;
|
||||||
const HASHED_PUBKEY_SERIALIZED_SIZE = 20;
|
const HASHED_PUBKEY_SERIALIZED_SIZE = 20;
|
||||||
const SIGNATURE_OFFSETS_SERIALIZED_SIZE = 11;
|
const SIGNATURE_OFFSETS_SERIALIZED_SIZE = 11;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ const SECP256K1_INSTRUCTION_LAYOUT = BufferLayout.struct([
|
||||||
BufferLayout.u16('messageDataOffset'),
|
BufferLayout.u16('messageDataOffset'),
|
||||||
BufferLayout.u16('messageDataSize'),
|
BufferLayout.u16('messageDataSize'),
|
||||||
BufferLayout.u8('messageInstructionIndex'),
|
BufferLayout.u8('messageInstructionIndex'),
|
||||||
BufferLayout.blob(20, 'ethPublicKey'),
|
BufferLayout.blob(20, 'ethAddress'),
|
||||||
BufferLayout.blob(64, 'signature'),
|
BufferLayout.blob(64, 'signature'),
|
||||||
BufferLayout.u8('recoveryId'),
|
BufferLayout.u8('recoveryId'),
|
||||||
]);
|
]);
|
||||||
|
@ -78,16 +78,16 @@ export class Secp256k1Program {
|
||||||
`Public key must be ${PUBLIC_KEY_BYTES} bytes`,
|
`Public key must be ${PUBLIC_KEY_BYTES} bytes`,
|
||||||
);
|
);
|
||||||
|
|
||||||
let ethPublicKey;
|
let ethAddress;
|
||||||
try {
|
try {
|
||||||
ethPublicKey = constructEthPubkey(publicKey);
|
ethAddress = constructEthAddress(publicKey);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`Error constructing ethereum public key: ${error}`);
|
throw new Error(`Error constructing ethereum public key: ${error}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataStart = 1 + SIGNATURE_OFFSETS_SERIALIZED_SIZE;
|
const dataStart = 1 + SIGNATURE_OFFSETS_SERIALIZED_SIZE;
|
||||||
const ethAddressOffset = dataStart;
|
const ethAddressOffset = dataStart;
|
||||||
const signatureOffset = dataStart + ethPublicKey.length;
|
const signatureOffset = dataStart + ethAddress.length;
|
||||||
const messageDataOffset = signatureOffset + signature.length + 1;
|
const messageDataOffset = signatureOffset + signature.length + 1;
|
||||||
const numSignatures = 1;
|
const numSignatures = 1;
|
||||||
|
|
||||||
|
@ -97,17 +97,17 @@ export class Secp256k1Program {
|
||||||
|
|
||||||
SECP256K1_INSTRUCTION_LAYOUT.encode(
|
SECP256K1_INSTRUCTION_LAYOUT.encode(
|
||||||
{
|
{
|
||||||
numSignatures: numSignatures,
|
numSignatures,
|
||||||
signatureOffset: signatureOffset,
|
signatureOffset,
|
||||||
signatureInstructionIndex: 0,
|
signatureInstructionIndex: 0,
|
||||||
ethAddressOffset: ethAddressOffset,
|
ethAddressOffset,
|
||||||
ethAddressInstructionIndex: 0,
|
ethAddressInstructionIndex: 0,
|
||||||
messageDataOffset: messageDataOffset,
|
messageDataOffset,
|
||||||
messageDataSize: message.length,
|
messageDataSize: message.length,
|
||||||
messageInstructionIndex: 0,
|
messageInstructionIndex: 0,
|
||||||
signature: toBuffer(signature),
|
signature: toBuffer(signature),
|
||||||
ethPublicKey: ethPublicKey,
|
ethAddress,
|
||||||
recoveryId: recoveryId,
|
recoveryId,
|
||||||
},
|
},
|
||||||
instructionData,
|
instructionData,
|
||||||
);
|
);
|
||||||
|
@ -135,7 +135,7 @@ export class Secp256k1Program {
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const publicKey = publicKeyCreate(privateKey, false);
|
const publicKey = publicKeyCreate(privateKey, false).slice(1); // throw away leading byte
|
||||||
const messageHash = Buffer.from(
|
const messageHash = Buffer.from(
|
||||||
keccak_256.update(toBuffer(message)).digest(),
|
keccak_256.update(toBuffer(message)).digest(),
|
||||||
);
|
);
|
||||||
|
@ -153,12 +153,10 @@ export class Secp256k1Program {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function constructEthPubkey(
|
function constructEthAddress(
|
||||||
publicKey: Buffer | Uint8Array | Array<number>,
|
publicKey: Buffer | Uint8Array | Array<number>,
|
||||||
): Buffer {
|
): Buffer {
|
||||||
return Buffer.from(
|
return Buffer.from(keccak_256.update(toBuffer(publicKey)).digest()).slice(
|
||||||
keccak_256
|
-HASHED_PUBKEY_SERIALIZED_SIZE,
|
||||||
.update(toBuffer(publicKey.slice(1))) // throw away leading byte
|
);
|
||||||
.digest(),
|
|
||||||
).slice(-HASHED_PUBKEY_SERIALIZED_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ if (process.env.TEST_LIVE) {
|
||||||
describe('secp256k1', () => {
|
describe('secp256k1', () => {
|
||||||
it('create secp256k1 instruction with public key', async () => {
|
it('create secp256k1 instruction with public key', async () => {
|
||||||
const privateKey = randomPrivateKey();
|
const privateKey = randomPrivateKey();
|
||||||
const publicKey = publicKeyCreate(privateKey, false);
|
const publicKey = publicKeyCreate(privateKey, false).slice(1);
|
||||||
const message = Buffer.from('This is a message');
|
const message = Buffer.from('This is a message');
|
||||||
const messageHash = Buffer.from(
|
const messageHash = Buffer.from(
|
||||||
keccak_256.update(toBuffer(message)).digest(),
|
keccak_256.update(toBuffer(message)).digest(),
|
||||||
|
|
Loading…
Reference in New Issue