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