Skip to content

Key Pair

The Karak SDK provides key pairs for various cryptographic curves. and it allows developers to create custom key pairs by following the provided traits, These pairs will be compatible with the Karak SDK.

Secp256k1 Keypair

For developers working with the secp256k1 curve, we recommend using the key pair functionality provided by Alloy, as it is fully compatible with Karak SDK.

BN254 Keypair

Karak SDK provides a keypair for the curve BN254.

Keypair Definition

The BN254 keypair has one secretKey and PublicKey. The secret key is an element in the scalar field. And the PublicKey struct comprises of two points g1 and g2 which lie on the groups G1 and G2 respectively

pub struct Keypair {
    secret_key: Fr,
    public_key: PublicKey,
}
 
pub struct PublicKey {
    pub g1: G1Pubkey,
    pub g2: G2Pubkey,
}

Example Usage

use karak_rs::kms::keypair::{bn254::Keypair, traits::Keypair as KeypairTrait};
 
fn keypair_demo() -> Result<Keypair> {
    // generate a random keypair for BN254
    let keypair = Keypair::generate();
 
    // retrieve secret key from BN254 keypair
    let keypair_secret_key = keypair.secret_key().0;
 
    // retrieve publicKey from BN254 keypair
    let keypair_public_key = keypair.public_key();
 
    let public_key_g1 = keypair_public_key.g1;
    let public_key_g2 = keypair_public_key.g2;
}

Keypair Trait

The Keypair Trait trait defines methods for generating and accessing cryptographic key pairs. If you wish to make a custom keypair that is compatible with Karak SDK then you can implement these following traits on your keypair.

pub trait Keypair: Display {
    type SecretKey;
    type PublicKey;
 
    fn generate() -> Self;
    fn secret_key(&self) -> &Self::SecretKey;
    fn public_key(&self) -> &Self::PublicKey;
}
  • generate: Creates a new key pair.
  • secret_key: Returns a reference to the secret key.
  • public_key: Returns a reference to the public key.

Encryptable Trait

The Encryptable trait provides methods for encrypting and decrypting key pairs:

pub trait Encryptable: Sized {
    type EncryptionError: Error + Send + Sync;
 
    fn encrypt(&self, passphrase: &str) -> Result<Vec<u8>, Self::EncryptionError>;
    fn decrypt(encrypted_keypair: &[u8], passphrase: &str) -> Result<Self, Self::EncryptionError>;
}
  • encrypt: Encrypts a key pair using a passphrase, returning the encrypted data.
  • decrypt: Decrypts an encrypted key pair using a passphrase.

Implementing Keypair traits for BN254

The SDK has a Keypair for the curve BN254. The process of making a BN254 keypair is as follows. A similar process can be used to create keypair for any curve.

pub struct Keypair {
    secret_key: Fr,
    public_key: PublicKey,
}
 
pub struct PublicKey {
    pub g1: G1Pubkey,
    pub g2: G2Pubkey,
}
  • Keypair: Contains a secret_key of type Fr(Field Element in Scalar Field) and a public_key of type PublicKey.
  • PublicKey: Holds g1 and g2, representing the public keys in G1 and G2 groups respectively.

The Keypair traits for the BN254 Keypair can be used as follows:

G1Affine is imported from ark_bn254, we will discuss more about that type in the BLS crate documentation

use super::traits::Keypair as KeypairTrait;
 
impl KeypairTrait for Keypair {
    type SecretKey = Fr;
    type PublicKey = PublicKey;
 
    fn generate() -> Self {
        let mut rng = thread_rng();
        let secret_key = Fr::rand(&mut rng);
        let g1_public_key = (G1Affine::generator() * secret_key).into_affine();
        let g2_public_key = (G2Affine::generator() * secret_key).into_affine();
 
        Self {
            secret_key,
            public_key: PublicKey {
                g1: g1_public_key.into(),
                g2: g2_public_key.into(),
            },
        }
    }
 
    fn secret_key(&self) -> &Self::SecretKey {
        &self.secret_key
    }
 
    fn public_key(&self) -> &Self::PublicKey {
        &self.public_key
    }
}

We have used an encryption method that uses encrypt_data_v3 to encrypt the data and decrypt_data_v3 to decrypt. However, you are free to use any encryption method of your choice. Using these functions we have implemented Encryptable for the BN254 Keypair as follows:

impl Encryptable for Keypair {
    type EncryptionError = KeypairEncryptionError;
 
    fn encrypt(&self, passphrase: &str) -> Result<Vec<u8>, KeypairEncryptionError> {
        let serialized_keypair = self.to_bytes()?;
        let encrypted_keypair =
            encryption::encrypt_data_v3(&serialized_keypair, passphrase.as_bytes(), 14, 1)?;
 
        Ok(bincode::serialize(&encrypted_keypair)?)
    }
 
    fn decrypt(encrypted_keypair: &[u8], passphrase: &str) -> Result<Self, KeypairEncryptionError> {
        let serialized_keypair = encryption::decrypt_data_v3(
            &bincode::deserialize(encrypted_keypair)?,
            passphrase.as_bytes(),
        )?;
 
        Ok(Keypair::try_from(serialized_keypair.as_slice())?)
    }
}

For all algebraic operations related to the BN254 curve, we utilize the ark_bn254 library. Further details on its application and integration with BLS signatures will be covered in the BLS section of the documentation.