Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for wasm32-pyodide #190

Merged
merged 30 commits into from
Feb 22, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1c95d7e
Added support for wasm32-pyodide
alarmfox Dec 27, 2024
4099d53
Removed match: not supported before python 3.10
alarmfox Dec 27, 2024
8f15021
Added test with good case
alarmfox Dec 27, 2024
2a721f8
Changed default parallelism=1 when platform.machine() = wasm32
alarmfox Dec 27, 2024
e1694cc
More robust platform checking
alarmfox Dec 28, 2024
fd48f0a
Testing under different platforms
alarmfox Dec 28, 2024
d3b6ecc
Added error message to UnsupportedParamsError
alarmfox Dec 30, 2024
25ca6f7
Added centralized functions for parameters validations and platform-c…
alarmfox Feb 12, 2025
23bb82b
Pre-commit
alarmfox Feb 12, 2025
a621190
Added test for PasswordHasher.from_parameters()
alarmfox Feb 12, 2025
5650323
Pre commit
alarmfox Feb 12, 2025
fb75e7d
Fix pre-commit
alarmfox Feb 12, 2025
fb5d68f
Fix test: made PasswordHasher.from_parameters easier to test
alarmfox Feb 12, 2025
d164813
Update src/argon2/exceptions.py
alarmfox Feb 12, 2025
79940f2
Merge branch 'hynek:main' into main
alarmfox Feb 12, 2025
b708393
Update tests/test_password_hasher.py
hynek Feb 22, 2025
da5c562
Update src/argon2/_password_hasher.py
hynek Feb 22, 2025
9f94cca
Update .python-version-default
hynek Feb 22, 2025
3697d8b
Update tests/test_password_hasher.py
hynek Feb 22, 2025
1e612bc
Update tests/test_password_hasher.py
hynek Feb 22, 2025
d89221f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 22, 2025
e85cc2d
Update src/argon2/profiles.py
hynek Feb 22, 2025
8cdc6d9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 22, 2025
622df98
Update src/argon2/_utils.py
hynek Feb 22, 2025
cfd873d
Update src/argon2/exceptions.py
hynek Feb 22, 2025
1959092
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 22, 2025
8361abc
Update tests/test_password_hasher.py
hynek Feb 22, 2025
c341964
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 22, 2025
86e2b27
Update tests/test_password_hasher.py
hynek Feb 22, 2025
bf70b4b
Update tests/test_password_hasher.py
hynek Feb 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions src/argon2/_password_hasher.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
from __future__ import annotations

import os
import platform

from typing import ClassVar, Literal

from ._utils import Parameters, _check_types, extract_parameters
from .exceptions import InvalidHashError
from .exceptions import InvalidHashError, UnsupportedParamsError
from .low_level import Type, hash_secret, verify_secret
from .profiles import RFC_9106_LOW_MEMORY

Expand All @@ -16,7 +17,9 @@
DEFAULT_HASH_LENGTH = RFC_9106_LOW_MEMORY.hash_len
DEFAULT_TIME_COST = RFC_9106_LOW_MEMORY.time_cost
DEFAULT_MEMORY_COST = RFC_9106_LOW_MEMORY.memory_cost
DEFAULT_PARALLELISM = RFC_9106_LOW_MEMORY.parallelism
DEFAULT_PARALLELISM = (
1 if platform.machine() == "wasm32" else RFC_9106_LOW_MEMORY.parallelism
)


def _ensure_bytes(s: bytes | str, encoding: str) -> bytes:
Expand Down Expand Up @@ -106,8 +109,7 @@ def __init__(
if e:
raise TypeError(e)

# Cache a Parameters object for check_needs_rehash.
self._parameters = Parameters(
params = Parameters(
type=type,
version=19,
salt_len=salt_len,
Expand All @@ -116,6 +118,12 @@ def __init__(
memory_cost=memory_cost,
parallelism=parallelism,
)
# verify params before accepting
if platform.machine() == "wasm32" and parallelism != 1:
raise UnsupportedParamsError

# Cache a Parameters object for check_needs_rehash.
self._parameters = params
self.encoding = encoding

@classmethod
Expand All @@ -128,6 +136,9 @@ def from_parameters(cls, params: Parameters) -> PasswordHasher:

.. versionadded:: 21.2.0
"""
# verify params before accepting
if platform.machine() == "wasm32" and params.parallelism != 1:
raise UnsupportedParamsError
ph = cls()
ph._parameters = params

Expand Down
8 changes: 8 additions & 0 deletions src/argon2/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ class InvalidHashError(ValueError):
"""


class UnsupportedParamsError(ValueError):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class needs to be added to the API docs.

"""
Raised if the current platform doesn not support the parameters.

Eg. In Wasm32, parallelism must be set to 1.
"""


InvalidHash = InvalidHashError
"""
Deprecated alias for :class:`InvalidHashError`.
Expand Down
27 changes: 26 additions & 1 deletion tests/test_password_hasher.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
# SPDX-License-Identifier: MIT

from unittest import mock

import pytest

from argon2 import PasswordHasher, Type, extract_parameters, profiles
from argon2._password_hasher import _ensure_bytes
from argon2.exceptions import InvalidHash, InvalidHashError
from argon2._utils import Parameters
from argon2.exceptions import (
InvalidHash,
InvalidHashError,
UnsupportedParamsError,
)


class TestEnsureBytes:
Expand Down Expand Up @@ -151,3 +158,21 @@ def test_type_is_configurable(self):
assert Type.I is ph.type is ph._parameters.type
assert Type.I is extract_parameters(ph.hash("foo")).type
assert ph.check_needs_rehash(default_hash)

def test_params_on_wasm32(self):
"""
Should fail if on wasm32 and parallelism > 1
"""
with mock.patch("platform.machine", return_value="wasm32"):
with pytest.raises(UnsupportedParamsError):
PasswordHasher(parallelism=2)

# last param is parallelism so it should fail
params = Parameters(Type.I, 2, 8, 8, 3, 256, 8)
with pytest.raises(UnsupportedParamsError):
ph = PasswordHasher.from_parameters(params)

# test normal execution
ph = PasswordHasher(parallelism=1)
hash = ph.hash("hello")
assert ph.verify(hash, "hello") is True
Loading