-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathArgon2.nim
158 lines (142 loc) · 3.52 KB
/
Argon2.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#Wrapper for the Argon2 C library that won the PHC competition.
#Get the current folder.
const currentFolder: string = currentSourcePath().substr(0, currentSourcePath().len - 11)
#Include the header.
{.passC: "-I" & currentFolder & "phc-winner-argon2/include".}
#Link against Argon2.
{.passL: "-L" & currentFolder & "phc-winner-argon2/".}
{.passL: "-largon2".}
#Define the Hash Type.
type Hash*[bits: static[int]] = object
data*: array[bits div 8, uint8]
#C proctions.
proc cArgon2d(
iterations: uint32,
memory: uint32,
parallelism: uint32,
data: ptr uint8,
dataLen: uint32,
salt: ptr uint8,
saltLen: uint32,
res: ptr uint8,
resLen: uint32
): cint {.
header: "argon2.h",
importc: "argon2d_hash_raw"
.}
proc cArgon2i(
iterations: uint32,
memory: uint32,
parallelism: uint32,
data: ptr uint8,
dataLen: uint32,
salt: ptr uint8,
saltLen: uint32,
res: ptr uint8,
resLen: uint32
): cint {.
header: "argon2.h",
importc: "argon2i_hash_raw"
.}
proc cArgon2id(
iterations: uint32,
memory: uint32,
parallelism: uint32,
data: ptr uint8,
dataLen: uint32,
salt: ptr uint8,
saltLen: uint32,
res: ptr uint8,
resLen: uint32
): cint {.
header: "argon2.h",
importc: "argon2id_hash_raw"
.}
#Take in data and a salt; return a Hash.
proc Argon2d*(
dataArg: string,
saltArg: string,
iterations: uint32,
memory: uint32,
parallelism: uint32
): Hash[256] =
#Extract the args.
var
data: string = dataArg
salt: string = saltArg
#Make sure the data exists.
if data == "":
data = $char(0)
#Make sure the salt is at least 8 characters long.
while salt.len < 8:
salt = char(0) & salt
if cArgon2d(
iterations,
memory,
parallelism,
cast[ptr uint8](addr data[0]),
uint32(data.len),
cast[ptr uint8](addr salt[0]),
uint32(salt.len),
addr result.data[0],
uint32(32)
) != 0:
raise newException(Exception, "Argon2 raised an error.")
proc Argon2i*(
dataArg: string,
saltArg: string,
iterations: uint32,
memory: uint32,
parallelism: uint32
): Hash[256] =
#Extract the args.
var
data: string = dataArg
salt: string = saltArg
#Make sure the data exists.
if data == "":
data = $char(0)
#Make sure the salt is at least 8 characters long.
while salt.len < 8:
salt = char(0) & salt
if cArgon2i(
iterations,
memory,
parallelism,
cast[ptr uint8](addr data[0]),
uint32(data.len),
cast[ptr uint8](addr salt[0]),
uint32(salt.len),
addr result.data[0],
uint32(32)
) != 0:
raise newException(Exception, "Argon2 raised an error.")
proc Argon2id*(
dataArg: string,
saltArg: string,
iterations: uint32,
memory: uint32,
parallelism: uint32
): Hash[256] =
#Extract the args.
var
data: string = dataArg
salt: string = saltArg
#Make sure the data exists.
if data == "":
data = $char(0)
#Make sure the salt is at least 8 characters long.
while salt.len < 8:
salt = char(0) & salt
if cArgon2id(
iterations,
memory,
parallelism,
cast[ptr uint8](addr data[0]),
uint32(data.len),
cast[ptr uint8](addr salt[0]),
uint32(salt.len),
addr result.data[0],
uint32(32)
) != 0:
raise newException(Exception, "Argon2 raised an error.")