Thanks to visit codestin.com
Credit goes to github.com

Skip to content
forked from w3f/schnorrkel

Schnorr VRFs and signatures on the Ristretto group

License

Notifications You must be signed in to change notification settings

mrkobold/schnorrkel

 
 

Repository files navigation

schnorrkel - Solana compatible

Verifies Polkadot's SR25519 signatures on Solana.

To use, add the following into Cargo.toml:

[dependencies]
schnorrkel = { git = "https://github.com/mrkobold/schnorrkel" }

Solana limits ComputeUnit usage per transaction to 1.4 million. Verifying SR25519 signatures don't fit into this limit.

The solution: do signature verification in steps/batches, saving and loading progress into a PDA between steps.

How to use

Create the following struct, which will be the data of the progress-saving-PDA

#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct DotSigCheckStruct {
    pub i: u64,
    pub projective_point: [u64; 15],
    pub signing_key: [u8; 32],
    pub message: [u8; 32],
    pub sig: [u8; 64],
}

Entering a signature verification step/batch from your code looks something like this:

pub fn verify<M: AsRef<[u8]>, F: Fn(usize, [u64; 15])>(
    sig: &[u8], // from PDA above
    message: M, // from PDA above
    pubkey: &[u8], // from PDA above
    update_pda_fn: F,
    i: usize,
    projective_point: [u64; 15],
) -> ProgramResult {
    msg!("sr25519.verify: {} more steps", i);
    let Ok(signature) = schnorrkel::Signature::from_bytes(sig) else {
        return Err(ERR_SIGNATURE_BYTES_INCORRECT);
    };

    let Ok(public) = schnorrkel::PublicKey::from_bytes(pubkey) else {
        return Err(ERR_PUB_KEY_BYTES_INCORRECT);
    };
    const SIGNING_CTX: &[u8] = b"substrate";
    let t = SigningContext::new(SIGNING_CTX).bytes(message.as_ref());

    let verify_res = public.step_verify(
        t,
        &signature,
        update_pda_fn,
        i,
        projective_point,
    );
    Ok(())
}

The update_pda_fn used in the flow looks like this:

fn update_pda_fn(i: usize, projective_point: [u64; 15], pda: AccountInfo) {
    let mut pda_bytes = pda.data.borrow_mut();
    let mut pda_struct: DotSigCheckStruct = DotSigCheckStruct::try_from_slice(&pda_bytes).unwrap();

    pda_struct.dot_sig_check_struct.i = i as u64;
    pda_struct.dot_sig_check_struct.projective_point = projective_point;

    pda_struct.serialize(&mut &mut srw_bytes[..]).unwrap();
}

About

Schnorr VRFs and signatures on the Ristretto group

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 100.0%