|
2 | 2 | use crate::xdr::ScVal; |
3 | 3 | use crate::{ |
4 | 4 | crypto::utils::BigInt, |
5 | | - env::internal::{self, BytesObject, U256Val}, |
| 5 | + env::internal::{self, BytesObject, U256Val, U64Val}, |
6 | 6 | impl_bytesn_repr_without_from_bytes, |
7 | 7 | unwrap::{UnwrapInfallible, UnwrapOptimized}, |
8 | 8 | Bytes, BytesN, ConversionError, Env, IntoVal, TryFromVal, Val, Vec, U256, |
9 | 9 | }; |
10 | 10 | use core::{ |
11 | 11 | cmp::Ordering, |
12 | 12 | fmt::Debug, |
13 | | - ops::{Add, Mul, Neg}, |
| 13 | + ops::{Add, Mul, Neg, Sub}, |
14 | 14 | }; |
15 | 15 |
|
16 | 16 | pub const BN254_FP_SERIALIZED_SIZE: usize = 32; // Size in bytes of a serialized Bn254Fp element in BN254. The field modulus is 254 bits, requiring 32 bytes (256 bits). |
@@ -254,6 +254,38 @@ impl Fr { |
254 | 254 | pub fn to_val(&self) -> Val { |
255 | 255 | self.0.to_val() |
256 | 256 | } |
| 257 | + |
| 258 | + pub fn pow(&self, rhs: u64) -> Self { |
| 259 | + self.env().crypto().bn254().fr_pow(self, rhs) |
| 260 | + } |
| 261 | + |
| 262 | + pub fn inv(&self) -> Self { |
| 263 | + self.env().crypto().bn254().fr_inv(self) |
| 264 | + } |
| 265 | +} |
| 266 | + |
| 267 | +impl Add for Fr { |
| 268 | + type Output = Fr; |
| 269 | + |
| 270 | + fn add(self, rhs: Self) -> Self::Output { |
| 271 | + self.env().crypto().bn254().fr_add(&self, &rhs) |
| 272 | + } |
| 273 | +} |
| 274 | + |
| 275 | +impl Sub for Fr { |
| 276 | + type Output = Fr; |
| 277 | + |
| 278 | + fn sub(self, rhs: Self) -> Self::Output { |
| 279 | + self.env().crypto().bn254().fr_sub(&self, &rhs) |
| 280 | + } |
| 281 | +} |
| 282 | + |
| 283 | +impl Mul for Fr { |
| 284 | + type Output = Fr; |
| 285 | + |
| 286 | + fn mul(self, rhs: Self) -> Self::Output { |
| 287 | + self.env().crypto().bn254().fr_mul(&self, &rhs) |
| 288 | + } |
257 | 289 | } |
258 | 290 |
|
259 | 291 | // BN254 scalar field modulus r in big-endian bytes. |
@@ -386,6 +418,59 @@ impl Bn254 { |
386 | 418 | .unwrap_infallible() |
387 | 419 | .into() |
388 | 420 | } |
| 421 | + |
| 422 | + /// Performs a multi-scalar multiplication (MSM) operation in G1. |
| 423 | + pub fn g1_msm(&self, vp: Vec<Bn254G1Affine>, vs: Vec<Fr>) -> Bn254G1Affine { |
| 424 | + let env = self.env(); |
| 425 | + let bin = internal::Env::bn254_g1_msm(env, vp.into(), vs.into()).unwrap_infallible(); |
| 426 | + unsafe { Bn254G1Affine::from_bytes(BytesN::unchecked_new(env.clone(), bin)) } |
| 427 | + } |
| 428 | + |
| 429 | + /// Checks if a G1 point is on the BN254 curve. |
| 430 | + pub fn g1_is_on_curve(&self, point: &Bn254G1Affine) -> bool { |
| 431 | + let env = self.env(); |
| 432 | + internal::Env::bn254_g1_is_on_curve(env, point.to_object()) |
| 433 | + .unwrap_infallible() |
| 434 | + .into() |
| 435 | + } |
| 436 | + |
| 437 | + // scalar arithmetic |
| 438 | + |
| 439 | + /// Adds two scalars in the BN254 scalar field `Fr`. |
| 440 | + pub fn fr_add(&self, lhs: &Fr, rhs: &Fr) -> Fr { |
| 441 | + let env = self.env(); |
| 442 | + let v = internal::Env::bn254_fr_add(env, lhs.into(), rhs.into()).unwrap_infallible(); |
| 443 | + U256::try_from_val(env, &v).unwrap_infallible().into() |
| 444 | + } |
| 445 | + |
| 446 | + /// Subtracts one scalar from another in the BN254 scalar field `Fr`. |
| 447 | + pub fn fr_sub(&self, lhs: &Fr, rhs: &Fr) -> Fr { |
| 448 | + let env = self.env(); |
| 449 | + let v = internal::Env::bn254_fr_sub(env, lhs.into(), rhs.into()).unwrap_infallible(); |
| 450 | + U256::try_from_val(env, &v).unwrap_infallible().into() |
| 451 | + } |
| 452 | + |
| 453 | + /// Multiplies two scalars in the BN254 scalar field `Fr`. |
| 454 | + pub fn fr_mul(&self, lhs: &Fr, rhs: &Fr) -> Fr { |
| 455 | + let env = self.env(); |
| 456 | + let v = internal::Env::bn254_fr_mul(env, lhs.into(), rhs.into()).unwrap_infallible(); |
| 457 | + U256::try_from_val(env, &v).unwrap_infallible().into() |
| 458 | + } |
| 459 | + |
| 460 | + /// Raises a scalar to the power of a given exponent in the BN254 scalar field `Fr`. |
| 461 | + pub fn fr_pow(&self, lhs: &Fr, rhs: u64) -> Fr { |
| 462 | + let env = self.env(); |
| 463 | + let rhs = U64Val::try_from_val(env, &rhs).unwrap_optimized(); |
| 464 | + let v = internal::Env::bn254_fr_pow(env, lhs.into(), rhs).unwrap_infallible(); |
| 465 | + U256::try_from_val(env, &v).unwrap_infallible().into() |
| 466 | + } |
| 467 | + |
| 468 | + /// Computes the multiplicative inverse of a scalar in the BN254 scalar field `Fr`. |
| 469 | + pub fn fr_inv(&self, lhs: &Fr) -> Fr { |
| 470 | + let env = self.env(); |
| 471 | + let v = internal::Env::bn254_fr_inv(env, lhs.into()).unwrap_infallible(); |
| 472 | + U256::try_from_val(env, &v).unwrap_infallible().into() |
| 473 | + } |
389 | 474 | } |
390 | 475 |
|
391 | 476 | #[cfg(test)] |
|
0 commit comments