Skip to content

Commit

Permalink
feat: expose API for EIP2333 key derivation
Browse files Browse the repository at this point in the history
  • Loading branch information
bochaco committed Dec 18, 2023
1 parent 78c26ea commit ac1f52f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
37 changes: 36 additions & 1 deletion ledger_device_sdk/src/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,19 @@ pub fn bip32_derive(curve: CurvesId, path: &[u32], key: &mut [u8]) -> Result<(),
Ok(())
}

/// Wrapper for 'os_perso_derive_eip2333'
pub fn eip2333_derive(path: &[u32], key: &mut [u8]) -> Result<(), CxError> {
unsafe {
os_perso_derive_eip2333(
CurvesId::Bls12381G1 as u8,
path.as_ptr(),
path.len() as u32,
key.as_mut_ptr(),
)
};
Ok(())
}

/// Helper buffer that stores secrets that need to be cleared after use
pub struct Secret<const N: usize>([u8; N]);

Expand Down Expand Up @@ -474,7 +487,7 @@ impl SeedDerive for Secp256r1 {
}

impl SeedDerive for Ed25519 {
type Target = ECPrivateKey<32, 'E'>;
type Target = ECPrivateKey<32, 'E'>; // TODO: review curve type
fn derive_from_path(path: &[u32]) -> Self::Target {
let mut tmp = Secret::<96>::new();
// Ignoring 'Result' here because known to be valid
Expand All @@ -495,6 +508,19 @@ impl SeedDerive for Stark256 {
}
}

impl SeedDerive for Bls12381G1 {
type Target = ECPrivateKey<32, 'E'>;
fn derive_from_path(path: &[u32]) -> Self::Target {
let mut tmp = Secret::<32>::new();
// Ignoring 'Result' here because known to be valid
let _ = eip2333_derive(path, tmp.as_mut());
let mut sk = Self::Target::new(CurvesId::Bls12381G1);
let keylen = sk.key.len();
sk.key.copy_from_slice(&tmp.0[..keylen]);
sk
}
}

/// This macro is used to easily generate zero-sized structures named after a Curve.
/// Each curve has a method `new()` that takes no arguments and returns the correctly
/// const-typed `ECPrivateKey`.
Expand Down Expand Up @@ -530,6 +556,7 @@ impl_curve!(BrainpoolP512R1, 64, 'W');
impl_curve!(BrainpoolP512T1, 64, 'W');
impl_curve!(Stark256, 32, 'W');
impl_curve!(Ed25519, 32, 'E');
impl_curve!(Bls12381G1, 32, 'E'); // TODO: review type of curve (...and sigining impl)
// impl_curve!( FRP256v1, 32, 'W' );
// impl_curve!( Ed448, 57, 'E' );

Expand Down Expand Up @@ -788,6 +815,14 @@ mod tests {
assert_eq!(pk.verify((&s.0, s.1), TEST_HASH, CX_SHA512), true);
}

#[test]
fn eddsa_bls12381g1() {
let sk = Bls12381G1::derive_from_path(&PATH0);
let s = sk.sign(TEST_HASH).map_err(display_error_code)?;
let pk = sk.public_key().map_err(display_error_code)?;
assert_eq!(pk.verify((&s.0, s.1), TEST_HASH, CX_SHA512), true);
}

#[test]
fn test_make_bip32_path() {
{
Expand Down
2 changes: 1 addition & 1 deletion ledger_device_sdk/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl From<SyscallError> for Reply {
// `Error` as `Infallible`. Since we need to convert such error in a status word (`Reply`) we need
// to implement this trait here.
impl From<Infallible> for Reply {
fn from(value: Infallible) -> Self {
fn from(_value: Infallible) -> Self {
Reply(0x9000)
}
}
Expand Down

0 comments on commit ac1f52f

Please sign in to comment.