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 asecret_key
of typeFr
(Field Element in Scalar Field) and apublic_key
of type PublicKey.PublicKey
: Holdsg1
andg2
, 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.