UNPKG

@covenance/dlc

Version:

Crypto and Bitcoin functions for Covenance DLC implementation

88 lines (77 loc) 2.85 kB
import { Point, utils, CURVE } from './secp256k1'; import { PrivKey, PubKey, Signature, EventOutcomeHash } from './types'; import { sha256, bytesToHex } from '../utils'; import { mod } from './general'; /** * Oracle function to create a commitment for an event in the future. * @param eventOutcomeHashes - Array of event outcome hashes for each potential event outcome * @param oraclePubKey - Oracle's public key * @returns Object containing array of event signature points and event nonce */ export async function commitToEvent( eventOutcomeHashes: EventOutcomeHash[], oraclePubKey: PubKey ): Promise<{ signaturePoints: Point[]; nonce: bigint }> { // Generate random nonce const nonce = utils.randomPrivateKey(); const nonceBigInt = BigInt('0x' + bytesToHex(nonce)); // Compute R = kG const R = Point.fromPrivateKey(nonce); // Compute signature points for each outcome const signaturePoints = await Promise.all(eventOutcomeHashes.map(async m_i => { // Compute H(R||V||m_i) const hashInput = new Uint8Array([ ...R.toRawBytes(true).slice(1), ...oraclePubKey.toRawBytes(true).slice(1), ...m_i ]); const hash = await sha256(hashInput); const e = mod(BigInt('0x' + bytesToHex(hash)), CURVE.n); // Compute S_i = R + H(R||V||m_i)V return R.add(oraclePubKey.multiply(e)); })); return { signaturePoints, nonce: nonceBigInt }; } /** * Oracle function to attest to an event outcome. * @param oraclePrivKey - Oracle's private key * @param nonce - Event nonce * @param eventOutcomeHash - Hash of the event outcome * @returns Oracle's signature for the event outcome */ export async function attestEventOutcome( oraclePrivKey: PrivKey, nonce: bigint, eventOutcomeHash: EventOutcomeHash ): Promise<Signature> { // Compute R = kG const nonceBytes = new Uint8Array(32); const nonceHex = nonce.toString(16).padStart(64, '0'); for (let i = 0; i < 32; i++) { nonceBytes[i] = parseInt(nonceHex.slice(i * 2, i * 2 + 2), 16); } const R = Point.fromPrivateKey(nonceBytes); // Get oracle's public key const V = Point.fromPrivateKey(oraclePrivKey); // Compute H(R||V||m_i) const hashInput = new Uint8Array([ ...R.toRawBytes(true).slice(1), ...V.toRawBytes(true).slice(1), ...eventOutcomeHash ]); const hash = await sha256(hashInput); const e = mod(BigInt('0x' + bytesToHex(hash)), CURVE.n); // Compute s_i = k + H(R||V||m_i)v const v = BigInt('0x' + bytesToHex(oraclePrivKey)); const s_i = mod(nonce + e * v, CURVE.n); return { R, s: s_i }; } /** * Function to extract the oracle's private key from two oracle outcome attestations. * This is to keep the oracle from cheating. */ /* c8 ignore start */ export function extractOraclePrivKey(): void { throw new Error('Not implemented'); } /* c8 ignore stop */