Groups

The CryptoGroups package provides a main API for working with cryptographic groups in a group-agnostic manner, supporting modular prime groups, elliptic curves over prime fields, and binary fields. This flexibility enables polymorphic implementations of standards like FIPS 186-4 digital signature algorithm to work seamlessly across different group types. Essential security checks, such as verifying point membership on elliptic curves or cofactor validation, are integrated into the constructors.

CryptoGroups encodes relevant group parameters as type parameter values, leveraging Julia's powerful type system to minimize the need for runtime assertions and ensure efficient memory use. This design allows for vector-like collections to be used without subtyping AbstractArray, resulting in a leaner and more predictable codebase. This also necessitates compiling every group, and are up to the user to decide which groups are needed for their applications.

CryptoGroups.ECGroupType
struct ECGroup{P<:ECPoint} <: Group
    x::P
end

Ellitpic curve group that maps ECPoint add and multiply to multiply and exponent semantics. The group can be instantiated from x, y coordinates ECGroup{P}(x, y) which are passed to corepsonding elliptic curve point constructor or via octet representation as specified in FIPS 186-4 standart. To construct the type use concretize_type or @ECGroup macro.

Example

p192_spec = spec(:P_192)
G = concretize_type(ECGroup, p192_spec)

# A macro syntax
G = @ECGroup{P_192}

If a group is instantiated from an existing specification then G() creates an instance of generator. A following ilustrates typical operations:

G = @ECGroup{P_192}
g = G()
g^3 * g^5/g^2 == (g^3)^2 == g^6
g^(order(G) - 1) * g == one(G)
one(G) * g == g
G(octet(g)) == G(value(g)) == g

See also octet, value, concretize_type, spec

source
CryptoGroups.GroupType
abstract type Group end

A cyclic group interface type. It is expected that constructor of the group does instance validation and throws an ArgumentError if it can't be constructed. Identity element can be constructed with explicit argument allow_one=true and validation can be opted out with skip_validation=true argument for the constructor which can be useful for deserialization from a secure location locally.

The group element shall support construction from vector of bytes (octet) as well as octet method itself. In addition value method is expected that provides most simple representation useful for debugging purposes. Given g::Group a following constructor methods are supported:

G = typeof(g)
g == G(octet(g)) == G(value(g))
one(G) == G(octet(one(G)), allow_one=true)

The group must support order, *, ^, rem and identity element via one. For concrete implementations see PGroup and ECGroup.

source
CryptoGroups.PGroupType
struct PGroup{S} <: Group
    g::BigInt
end

Modulus prime group where S is a static type parameter encoding group properties. To instantiate a concrete type use a macor @PGroup or use concretize_type.

Example

# Directly passing type arguments
G = concretize_type(PGroup, 23, 11) # where modulus is 23 and order is 11

# Using a macro for user specification
G = @PGroup{p = 23, q = 11}

# Using existing specification
modp = spec(:RFC5114_2048_224)
G = concretize_type(PGroup, modp)

# Using a macro for existing specification
G = @PGroup{RFC5114_2048_224}

If a group is instantiated from an existing specification then G() creates an instance of generator. A following ilustrates typical operations:

G = @PGroup{p = 23, q = 11}
g = G(2)
g^3 * g^5/g^2 == (g^3)^2 == g^6
g^(order(G) - 1) * g == one(G)
one(G) * g == g
G(octet(g)) == G(value(g)) == g

See also octet, value, concretize_type, spec

source
Base.:*Method
*(x::G, y::G)::G where G <: Group

Multiplies two group elements.

source
Base.:/Method
/(x::G, y::G)::G where G <: Group

Convinience method for x * inv(y)

source
Base.:^Method
^(x::G, n::Integer)::G where G <: Group

Exponentiates the group element. In case mod(n, order(G)) == 0 throws an error in strict mode or shows a warning in relaxed mode.

See also isstrict and set_strict_mode

source
Base.convertMethod
convert(::Type{G}, x; allow_one=false)::G where G <: Group

Converts representation of x into a group element type G. The conversion is safe as the validation checks are performed within group constructors. In case identity element needs to be read into allow_one flag can be used to allow constructing identity elements.

source
Base.invMethod
inv(g::G)::G where G <: Group

Computes inverse of the group element so that inv(g) * g == one(G)

source
Base.oneMethod
one(::Type{G}) where G

Construct an identity element of the group.

source
Base.remMethod
rem(x::ECGroup, q::T)::T where T <: Integer

Computes remainder of the elliptic curve point

source
Base.remMethod
rem(x::PGroup, q::T)::T where T <: Integer

Computes remainder of a prime group integer value

source
CryptoGroups.Fields.modulusMethod
modulus(::Union{G, Type{G}})::BigInt where G <: PGroup

Modulus of a prime group. It is not recommended to depend on this method in the codebase as it destroys polymorphism.

source
CryptoGroups.Fields.octetMethod
octet(g::ECGroup; mode = :uncompressed|:hybrid|:compressed)::Vector{UInt8}

Converts elliptic curve point to an octet representation as specified in FIPS 186-4 standart. The mode=:uncompressed|:hybrid|:compressed can be used to specify compression mode.

See also iscompressable

source
CryptoGroups.Fields.octetMethod
octet(x::PGroup)::Vector{UInt8}

Converts modulus prime group element into octet representation. A padding is added to match the length of modulus.

source
CryptoGroups.concretize_typeFunction
concretize_type(::Type{T}, args...) <: T where T

Constructs a concrete subtype of union all or abstract type T. The arguments args are used to set concrtete values for type parameters of T, effectivelly concretizing a generic abstract type. The resulting type then can be instanitated by a value.

See also spec

source
CryptoGroups.iscompressableMethod
iscompressable(g::Group)::Bool

Returns true if octet function accepts mode=:compressed as is groups based on eliptic curves. Currently for binary curves decompression is not implemented and hence this method returns false for them.

source
CryptoGroups.specFunction
spec(::Union{G, Type{G}})::GroupSpec where G <: Group

Constructs a specification of a group type or instance. It's general intended use is for debugging purposes and serves as an inverse to concretize_type method. If called with a group instance the the value of it is used for a generator for the group specification otherwise it is left empty.

See also concretize_type

source
CryptoGroups.specMethod
spec(name::Symbol)::GroupSpec

Gets a group specification from a provided canonical name of the group specification which are hardcoded into the library.

Examples

# NIST elliptic curve P-192 specification:
p192_spec = spec(:P_192)
P192 = concretize_type(ECGroup, p192_spec)

# Modular prime group specification
modp_spec = spec(:RFC5114_2048_224)
MODP = concretize_type(PGroup, modp_spec)

See also concretize_type, @ECGroup, @PGroup

source
CryptoGroups.valueMethod
value(g::Group)::Union{BigInt, Tuple{BigInt, BigInt}, Tuple{BitVector, BitVector}}

Converts the group instance to the most simple representation. Generally intended for debugging purposes and for serialization one should use octet as it also ensures consistent padding.

See also octet, Curves.gx, Curves.gy

source