Skip to content

Commit

Permalink
add secp384r1 curve for openssl demo
Browse files Browse the repository at this point in the history
  • Loading branch information
5HT committed Oct 23, 2024
1 parent b9b7e09 commit 9d61265
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 15 deletions.
33 changes: 24 additions & 9 deletions lib/curves/ecdsa.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ defmodule CA.ECDSA do
require CA.Jacobian
require CA.ECDSA.OTP

def numberFromString(data) do
Base.encode16(data)
|> Integer.parse(16)
|> (fn {parsedInt, ""} -> parsedInt end).()
end

def sign(message, privateKey, options \\ []) do
%{hashfunc: hashfunc} = Enum.into(options, %{hashfunc: :sha256})
number = :crypto.hash(hashfunc, message) |> numberFromString()
Expand All @@ -26,16 +20,37 @@ defmodule CA.ECDSA do
def public(bin), do: #:erlang.element(1,:erlang.element(2,
:public_key.pem_entry_decode(hd(:public_key.pem_decode(bin)))

def verify(file, signature, pub) do
def numberFromString(string) do
Base.encode16(string)
|> Integer.parse(16)
|> (fn {parsedInt, ""} -> parsedInt end).()
end

def decodeIntegerFromECPoint(ec) do
{{:ECPoint, bin2}, {:namedCurve, oid}} = ec
bin = :binary.part(bin2,1,:erlang.size(bin2)-1)
curve = CA.KnownCurves.getCurveByOid(oid)
baseLength = CA.Curve.getLength(curve)
xs = :binary.part(bin, 0, baseLength)
ys = :binary.part(bin, baseLength, :erlang.size(bin) - baseLength)
point = %CA.Point{ x: numberFromString(xs), y: numberFromString(ys)}
:io.format 'ECPoint.x: ~p~n', [xs]
:io.format 'ECPoint.y: ~p~n', [ys]
:io.format 'ECPoint: ~p~n', [point]
point
end

def verify(file, signature_file, pub) do
{:ok, msg} = :file.read_file file
{:ok, pem} = :file.read_file pub
verify(msg, CA.ECDSA.OTP.signature(signature), public(pem), [])
verify(msg, CA.ECDSA.OTP.signature(signature_file), decodeIntegerFromECPoint(public(pem)), [])
end

def verify(message, {r,s}, publicKey, options) do
:io.format '{r,s}: ~p~n', [{r,s}]
%{hashfunc: hashfunc} = Enum.into(options, %{hashfunc: :sha256})
number = :crypto.hash(hashfunc, message) |> numberFromString()
curve = CA.KnownCurves.secp256k1()
curve = CA.KnownCurves.secp384r1()
inv = CA.Jacobian.inv(s, curve."N")
v = CA.Jacobian.add(
CA.Jacobian.multiply(curve."G", CA.Integer.modulo(number * inv, curve."N"),
Expand Down
27 changes: 23 additions & 4 deletions lib/curves/knownCurves.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@ defmodule CA.KnownCurves do
require CA.Curve
require CA.Point

@secp256k1Oid {1, 3, 132, 0, 10}
@secp256k1name :secp256k1
@secp384r1 {1, 3, 132, 0, 34}
@secp256k1 {1, 3, 132, 0, 10}
@prime256v1 {1, 2, 840, 10045, 3, 1, 7}
@secp384r1name :secp384r1
@secp256k1name :secp256k1
@prime256v1name :prime256v1

def getCurveByOid(oid) do
case oid do
@secp256k1Oid -> secp256k1()
@secp256k1 -> secp256k1()
@secp384r1 -> secp384r1()
@prime256v1 -> prime256v1()
end
end

def getCurveByName(name) do
case name do
@secp256k1name -> secp256k1()
@secp384r1name -> secp384r1()
@prime256v1name -> prime256v1()
end
end
Expand All @@ -32,7 +36,7 @@ defmodule CA.KnownCurves do
x: 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
y: 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
},
oid: @secp256k1Oid
oid: @secp256k1
}
end

Expand All @@ -50,4 +54,19 @@ defmodule CA.KnownCurves do
oid: @prime256v1
}
end

def secp384r1() do
%CA.Curve{
name: @secp384r1name,
A: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc,
B: 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef,
P: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff,
N: 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973,
G: %CA.Point{
x: 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7,
y: 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f
},
oid: @secp384r1
}
end
end
6 changes: 5 additions & 1 deletion lib/ecdsa.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ defmodule CA.ECDSA.OTP do

def verifyBin(msg, sig, pub) do
{CA."ECPoint"(point: point), {:namedCurve, oid}} = pub
:io.format 'oid: ~p~n', [oid]
:crypto.verify(:ecdsa, :sha256, msg, sig,
[point, :crypto.ec_curve(:pubkey_cert_records.namedCurves(oid))])
end

def signature(name) do
{:ok, sig} = :file.read_file name
{{_,[{_,r},{_,s}]},""} = :asn1rt_nif.decode_ber_tlv sig
{r,s}
:io.format 'r: ~p~n', [r]
:io.format 's: ~p~n', [s]
{ :ca_enroll.decode_integer(r),
:ca_enroll.decode_integer(s) }
end

def sign(file, priv) do
Expand Down
7 changes: 6 additions & 1 deletion src/ca_enroll.erl
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
-module(ca_enroll).
-copyright('Namdak Tonpa').
-include_lib("public_key/include/public_key.hrl").
-export([init/2, boot/0, boot/1, cwd/0, ca/1, enroll/3, service/3, maybe_service/3, echo/2]).
-export([init/2, boot/0, boot/1, cwd/0, ca/1, enroll/3, service/3, maybe_service/3, echo/2, decode_integer/1]).

decode_integer(Bin) ->
Len = byte_size(Bin),
<<Int:Len/signed-unit:8>> = Bin,
Int.

init(Req,Opts) ->
Method = cowboy_req:method(Req),
Expand Down

0 comments on commit 9d61265

Please sign in to comment.