--
-- Tests for argon2id
--

--
-- Reference source comparison to python passlib
--

--
-- Compare hash values formerly derived by python passlib with default settings
--
-- Hash created by pythons' passlib:

-- from passlib.hash import argon2
-- h = (argon2.hash("password"))
-- h = (argon2.using(type="I").using(rounds=32).hash("password"))
-- h = (argon2.using(rounds=12).using(memory_cost=524144).hash("password"))

-- Needs to be off, since python's passlib doesn't pad at all
SET pg_pwhash.always_pad_base64 TO off;

--------------------------------------
-- Tests with default OpenSSL backend
--------------------------------------

-- With Argon2id

SELECT pwhash_argon2('password', '$argon2id$v=19$m=65536,t=3,p=4$u9ca4zxn7H0PISSE0HqP8Q$yeN3V5sfotE6xjbD+1oBNXyF6ZkgDAlsrnJvYbOgbY4') = '$argon2id$v=19$m=65536,t=3,p=4$u9ca4zxn7H0PISSE0HqP8Q$yeN3V5sfotE6xjbD+1oBNXyF6ZkgDAlsrnJvYbOgbY4';

SELECT pwhash_argon2('password', '$argon2id$v=19$m=65536,t=32,p=4$nHNOyRkjBMDYW8sZo7S29g$iNUvxeJFuWD8J80LlQ1G1uJ9rRIYSBMM11vQP6YJLec') = '$argon2id$v=19$m=65536,t=32,p=4$nHNOyRkjBMDYW8sZo7S29g$iNUvxeJFuWD8J80LlQ1G1uJ9rRIYSBMM11vQP6YJLec';

SELECT pwhash_argon2('password', '$argon2id$v=19$m=524144,t=12,p=4$x3gPgZBybs05x/g/R4ix1g$PdtQc0Ew4cmDTjlgONywuuRymhVqricqoV+t0L3+7fI') = '$argon2id$v=19$m=524144,t=12,p=4$x3gPgZBybs05x/g/R4ix1g$PdtQc0Ew4cmDTjlgONywuuRymhVqricqoV+t0L3+7fI';

-- Same with Argon2i
SELECT pwhash_argon2('password', '$argon2i$v=19$m=65536,t=3,p=4$3JsTYkxJyXmPsbbW+h+DEA$PfNhqviX6Vdir2yjZGvdNsZBtyGGK6OspQ8dBHKtxjw') = '$argon2i$v=19$m=65536,t=3,p=4$3JsTYkxJyXmPsbbW+h+DEA$PfNhqviX6Vdir2yjZGvdNsZBtyGGK6OspQ8dBHKtxjw';

SELECT pwhash_argon2('password', '$argon2i$v=19$m=65536,t=32,p=4$KwVgjNE6B8A4x1gLQUgJ4Q$lIKr0C06qclmZ2hMt0hfEYa2zVIxoUrRyL4WqZEM9Ik') = '$argon2i$v=19$m=65536,t=32,p=4$KwVgjNE6B8A4x1gLQUgJ4Q$lIKr0C06qclmZ2hMt0hfEYa2zVIxoUrRyL4WqZEM9Ik';

SELECT pwhash_argon2('password', '$argon2i$v=19$m=65536,t=32,p=4$g/C+9/6/N+Zca+39v/e+Vw$hwV/1QN+JWWaAyuj2iG79m/fnsfK8V64VObms58aNKY') = '$argon2i$v=19$m=65536,t=32,p=4$g/C+9/6/N+Zca+39v/e+Vw$hwV/1QN+JWWaAyuj2iG79m/fnsfK8V64VObms58aNKY';

-- And Argon2d
SELECT pwhash_argon2('password', '$argon2i$v=19$m=65536,t=3,p=4$QChlbI0xRgjBOOe8t3au1Q$8Qb01rXObi+4PsLGKLabqlSN/kWpBPR/otSZYSIX04c') = '$argon2i$v=19$m=65536,t=3,p=4$QChlbI0xRgjBOOe8t3au1Q$8Qb01rXObi+4PsLGKLabqlSN/kWpBPR/otSZYSIX04c';

--
-- Compare hashes generated by Argon2 reference implementation
--
-- The hashes which are compared are generated by the argon2 CLI tool like this:
--
-- echo -n password | argon2 12345678 -id -k 65536 -p 4 -e
--

SELECT pwhash_argon2('password', '$argon2id$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$2sE3QrtIr+1LWoXKNOp78utMyP0aUrKzzJaDjgNWaac') = '$argon2id$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$2sE3QrtIr+1LWoXKNOp78utMyP0aUrKzzJaDjgNWaac';

-- echo -n password | argon2 12345678 -id -k 4096 -p 1 -e
SELECT pwhash_argon2('password', '$argon2id$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$5yr8dXSYcZjcMH5jBzwNm0D84iQOKLGLOWsQeKUUHpE') = '$argon2id$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$5yr8dXSYcZjcMH5jBzwNm0D84iQOKLGLOWsQeKUUHpE';

-- salt length not divisible by 4 (will be padded by OpenSSL)
-- echo -n password | argon2 123456789 -id -k 4096 -p 1 -e

SELECT pwhash_argon2('password', '$argon2id$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5MA$pptxGYuibkAGG9bVRNAxgEv6/OMVVEahqS8vEmo/B2g') = '$argon2id$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5MA$pptxGYuibkAGG9bVRNAxgEv6/OMVVEahqS8vEmo/B2g';

--
-- same with Argon2i
--
-- echo -n password | argon2 12345678 -i -k 65536 -p 4 -e
--

SELECT pwhash_argon2('password', '$argon2i$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$BvKUwNCmr7GPzmR+EyZJdBTOWvRPvaz2lNpZgWdAN3A') = '$argon2i$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$BvKUwNCmr7GPzmR+EyZJdBTOWvRPvaz2lNpZgWdAN3A';

-- echo -n password | argon2 12345678 -i -k 4096 -p 1 -e
SELECT pwhash_argon2('password', '$argon2i$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$y8JaUwdNBwIXjh8MsBXCpGZ/avW2uhupKJsomvqnyiY') = '$argon2i$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$y8JaUwdNBwIXjh8MsBXCpGZ/avW2uhupKJsomvqnyiY';

-- salt length not divisible by 4 (will be padded by OpenSSL)
-- echo -n password | argon2 123456789 -i -k 4096 -p 1 -e

SELECT pwhash_argon2('password', '$argon2i$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5$oB0yBJVFa/Q9LPtmGL6SpjeaKg++Cloipto5OiYzCRU') = '$argon2i$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5$oB0yBJVFa/Q9LPtmGL6SpjeaKg++Cloipto5OiYzCRU';

--
-- Same with Argon2d
--
-- echo -n password | argon2 12345678 -d -k 65536 -p 4 -e

SELECT pwhash_argon2('password', '$argon2d$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$h+HoUsia1leIw6QQtzEFgergF3Ccud96oLEaS0ZOnMU') = '$argon2d$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$h+HoUsia1leIw6QQtzEFgergF3Ccud96oLEaS0ZOnMU';

-- echo -n password | argon2 12345678 -d -k 4096 -p 1 -e
SELECT pwhash_argon2('password', '$argon2d$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$YDBvrlalKVUif4UV+7RYk2s6F1ucueZZ/BibQz4zsa8') = '$argon2d$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$YDBvrlalKVUif4UV+7RYk2s6F1ucueZZ/BibQz4zsa8';

-- salt length not divisible by 4 (will be padded by OpenSSL)
-- echo -n password | argon2 123456789 -d -k 4096 -p 1 -e
SELECT pwhash_argon2('password', '$argon2d$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5$TW92egXZew84K8pX5fIX9IGN0i6FplcIioHC7J1aqSc') = '$argon2d$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5$TW92egXZew84K8pX5fIX9IGN0i6FplcIioHC7J1aqSc';

--------------------------------------
-- Tests with libargon2
--------------------------------------

-- With Argon2id
SET pg_pwhash.argon2_default_backend TO 'libargon2';

SELECT pwhash_argon2('password', '$argon2id$v=19$m=65536,t=3,p=4$u9ca4zxn7H0PISSE0HqP8Q$yeN3V5sfotE6xjbD+1oBNXyF6ZkgDAlsrnJvYbOgbY4') = '$argon2id$v=19$m=65536,t=3,p=4$u9ca4zxn7H0PISSE0HqP8Q$yeN3V5sfotE6xjbD+1oBNXyF6ZkgDAlsrnJvYbOgbY4';

SELECT pwhash_argon2('password', '$argon2id$v=19$m=65536,t=32,p=4$nHNOyRkjBMDYW8sZo7S29g$iNUvxeJFuWD8J80LlQ1G1uJ9rRIYSBMM11vQP6YJLec') = '$argon2id$v=19$m=65536,t=32,p=4$nHNOyRkjBMDYW8sZo7S29g$iNUvxeJFuWD8J80LlQ1G1uJ9rRIYSBMM11vQP6YJLec';

SELECT pwhash_argon2('password', '$argon2id$v=19$m=524144,t=12,p=4$x3gPgZBybs05x/g/R4ix1g$PdtQc0Ew4cmDTjlgONywuuRymhVqricqoV+t0L3+7fI') = '$argon2id$v=19$m=524144,t=12,p=4$x3gPgZBybs05x/g/R4ix1g$PdtQc0Ew4cmDTjlgONywuuRymhVqricqoV+t0L3+7fI';

-- Same with Argon2i
SELECT pwhash_argon2('password', '$argon2i$v=19$m=65536,t=3,p=4$3JsTYkxJyXmPsbbW+h+DEA$PfNhqviX6Vdir2yjZGvdNsZBtyGGK6OspQ8dBHKtxjw') = '$argon2i$v=19$m=65536,t=3,p=4$3JsTYkxJyXmPsbbW+h+DEA$PfNhqviX6Vdir2yjZGvdNsZBtyGGK6OspQ8dBHKtxjw';

SELECT pwhash_argon2('password', '$argon2i$v=19$m=65536,t=32,p=4$KwVgjNE6B8A4x1gLQUgJ4Q$lIKr0C06qclmZ2hMt0hfEYa2zVIxoUrRyL4WqZEM9Ik') = '$argon2i$v=19$m=65536,t=32,p=4$KwVgjNE6B8A4x1gLQUgJ4Q$lIKr0C06qclmZ2hMt0hfEYa2zVIxoUrRyL4WqZEM9Ik';

SELECT pwhash_argon2('password', '$argon2i$v=19$m=65536,t=32,p=4$g/C+9/6/N+Zca+39v/e+Vw$hwV/1QN+JWWaAyuj2iG79m/fnsfK8V64VObms58aNKY') = '$argon2i$v=19$m=65536,t=32,p=4$g/C+9/6/N+Zca+39v/e+Vw$hwV/1QN+JWWaAyuj2iG79m/fnsfK8V64VObms58aNKY';

-- And Argon2d
SELECT pwhash_argon2('password', '$argon2i$v=19$m=65536,t=3,p=4$QChlbI0xRgjBOOe8t3au1Q$8Qb01rXObi+4PsLGKLabqlSN/kWpBPR/otSZYSIX04c') = '$argon2i$v=19$m=65536,t=3,p=4$QChlbI0xRgjBOOe8t3au1Q$8Qb01rXObi+4PsLGKLabqlSN/kWpBPR/otSZYSIX04c';

--
-- Compare hashes generated by Argon2 reference implementation
--
-- The hashes which are compared are generated by the argon2 CLI tool like this:
--
-- echo -n password | argon2 12345678 -id -k 65536 -p 4 -e
--

SELECT pwhash_argon2('password', '$argon2id$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$2sE3QrtIr+1LWoXKNOp78utMyP0aUrKzzJaDjgNWaac') = '$argon2id$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$2sE3QrtIr+1LWoXKNOp78utMyP0aUrKzzJaDjgNWaac';

-- echo -n password | argon2 12345678 -id -k 4096 -p 1 -e
SELECT pwhash_argon2('password', '$argon2id$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$5yr8dXSYcZjcMH5jBzwNm0D84iQOKLGLOWsQeKUUHpE') = '$argon2id$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$5yr8dXSYcZjcMH5jBzwNm0D84iQOKLGLOWsQeKUUHpE';

-- salt length not divisible by 4 (will be padded by OpenSSL)
-- echo -n password | argon2 123456789 -id -k 4096 -p 1 -e

SELECT pwhash_argon2('password', '$argon2id$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5MA$pptxGYuibkAGG9bVRNAxgEv6/OMVVEahqS8vEmo/B2g') = '$argon2id$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5MA$pptxGYuibkAGG9bVRNAxgEv6/OMVVEahqS8vEmo/B2g';

--
-- same with Argon2i
--
-- echo -n password | argon2 12345678 -i -k 65536 -p 4 -e
--

SELECT pwhash_argon2('password', '$argon2i$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$BvKUwNCmr7GPzmR+EyZJdBTOWvRPvaz2lNpZgWdAN3A') = '$argon2i$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$BvKUwNCmr7GPzmR+EyZJdBTOWvRPvaz2lNpZgWdAN3A';

-- echo -n password | argon2 12345678 -i -k 4096 -p 1 -e
SELECT pwhash_argon2('password', '$argon2i$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$y8JaUwdNBwIXjh8MsBXCpGZ/avW2uhupKJsomvqnyiY') = '$argon2i$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$y8JaUwdNBwIXjh8MsBXCpGZ/avW2uhupKJsomvqnyiY';

-- salt length not divisible by 4 (will be padded by OpenSSL)
-- echo -n password | argon2 123456789 -i -k 4096 -p 1 -e

SELECT pwhash_argon2('password', '$argon2i$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5$oB0yBJVFa/Q9LPtmGL6SpjeaKg++Cloipto5OiYzCRU') = '$argon2i$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5$oB0yBJVFa/Q9LPtmGL6SpjeaKg++Cloipto5OiYzCRU';

--
-- Same with Argon2d
--
-- echo -n password | argon2 12345678 -d -k 65536 -p 4 -e

SELECT pwhash_argon2('password', '$argon2d$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$h+HoUsia1leIw6QQtzEFgergF3Ccud96oLEaS0ZOnMU') = '$argon2d$v=19$m=65536,t=3,p=4$MTIzNDU2Nzg$h+HoUsia1leIw6QQtzEFgergF3Ccud96oLEaS0ZOnMU';

-- echo -n password | argon2 12345678 -d -k 4096 -p 1 -e
SELECT pwhash_argon2('password', '$argon2d$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$YDBvrlalKVUif4UV+7RYk2s6F1ucueZZ/BibQz4zsa8') = '$argon2d$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$YDBvrlalKVUif4UV+7RYk2s6F1ucueZZ/BibQz4zsa8';

-- salt length not divisible by 4 (will be padded by OpenSSL)
-- echo -n password | argon2 123456789 -d -k 4096 -p 1 -e
SELECT pwhash_argon2('password', '$argon2d$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5$TW92egXZew84K8pX5fIX9IGN0i6FplcIioHC7J1aqSc') = '$argon2d$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg5$TW92egXZew84K8pX5fIX9IGN0i6FplcIioHC7J1aqSc';

RESET pg_pwhash.argon2_default_backend;

----------------------------------------------------------
-- Test generating Argon2 hashes with pwhash_gen_salt()
----------------------------------------------------------

CREATE TABLE pwhash_test_argon2(pw text NOT NULL, salt text NOT NULL, hash text);
INSERT INTO pwhash_test_argon2(pw, salt) VALUES('password', pwhash_gen_salt('argon2id','memcost=4096', 'parallelism=1', 'rounds=3'));
UPDATE pwhash_test_argon2 SET hash = pwhash_argon2('password', salt) WHERE pw = 'password';

SELECT hash = pwhash_argon2(pw, salt) FROM pwhash_test_argon2;

DELETE FROM pwhash_test_argon2;

-- choose libargon2 backend via salt settings
INSERT INTO pwhash_test_argon2(pw, salt) VALUES('password', pwhash_gen_salt('argon2id','memcost=4096', 'parallelism=1', 'rounds=3', 'backend=libargon2'));
UPDATE pwhash_test_argon2 SET hash = pwhash_argon2('password', salt) WHERE pw = 'password';

SELECT hash = pwhash_argon2(pw, salt) FROM pwhash_test_argon2;

DELETE FROM pwhash_test_argon2;

-- switch hash backends in between
RESET pg_pwhash.argon2_default_backend;
SHOW pg_pwhash.argon2_default_backend;
INSERT INTO pwhash_test_argon2(pw, salt) VALUES('password', pwhash_gen_salt('argon2id','memcost=4096', 'parallelism=1', 'rounds=3'));
UPDATE pwhash_test_argon2 SET hash = pwhash_argon2('password', salt) WHERE pw = 'password';

SET pg_pwhash.argon2_default_backend TO 'libargon2';
SHOW pg_pwhash.argon2_default_backend;

SELECT hash = pwhash_argon2(pw, salt) FROM pwhash_test_argon2;
RESET pg_pwhash.argon2_default_backend;

DROP TABLE pwhash_test_argon2;
