Macro secp256kfun::g
source · macro_rules! g { ($($t:tt)*) => { ... }; }
Expand description
Group operation expression macro.
The g!
macro lets you express scalar multiplications and group operations conveniently
following standard order of operations. This compiles down to operations from the op
module. Apart from being far more readable, the idea is that g!
will (or may in the future)
compile to more efficient operations than if you were to manually call the functions from op
yourself.
Note you can but often don’t need to put a &
in front of the terms in the expression.
§Syntax and operations
The expression supports the following operations:
<scalar> * <point>
multiplies thepoint
byscalar
<point> + <point>
adds two points<point> - <point>
subtracts one point from another<scalar_iter> .* <point_iter>
does a dot product between a list of points and scalars. If one list is shorter than the other then the excess points or scalars will be multiplied by 0. Seeop::point_scalar_dot_product
.
The terms of the expression can be any variable followed by simple method calls, attribute
access etc. If your term involves more expressions (anything involving specifying types using
::
) then you can use {..}
to surround arbitrary expressions. You can also use (..)
to
group arithmetic expressions to override the usual operation order.
§Examples
Simple scalar multiplication by G
but will work with any Point
use secp256kfun::{g, Scalar, G};
let x = Scalar::random(&mut rand::thread_rng());
let X = g!(x * G);
A more complicated set of expressions.
let x = Scalar::random(&mut rand::thread_rng());
let y = Scalar::random(&mut rand::thread_rng());
let H = Point::random(&mut rand::thread_rng());
let minus = g!(x * G - y * H);
let plus = g!(x * G + y * H);
assert_eq!(g!(plus + minus), g!(2 * x * G)); // this will do 2 * x first
assert_eq!(g!(42 * (G + H)), g!((42 * G + 42 * H)));
You may access attributes and call methods:
struct DoMul {
scalar: Scalar,
point: Point,
}
let mul = DoMul {
scalar: Scalar::random(&mut rand::thread_rng()),
point: Point::random(&mut rand::thread_rng()),
};
let result = g!(mul.scalar * mul.point);
assert_eq!(g!(mul.scalar.invert() * result), mul.point);
You can put an arbitrary expressions inside {...}
let random_point = g!({ Scalar::random(&mut rand::thread_rng()) } * G);