mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-24 23:38:09 +00:00
chore(vendor): update secp256k1-zkp to latest
This commit is contained in:
parent
38ad9ab9e5
commit
db0da196a8
1
core/.changelog.d/2261.changed
Normal file
1
core/.changelog.d/2261.changed
Normal file
@ -0,0 +1 @@
|
|||||||
|
Updated secp256k1-zkp.
|
@ -122,13 +122,7 @@ if FEATURE_FLAGS["SECP256K1_ZKP"]:
|
|||||||
'USE_SECP256K1_ZKP_ECDSA',
|
'USE_SECP256K1_ZKP_ECDSA',
|
||||||
('SECP256K1_CONTEXT_SIZE', '184'),
|
('SECP256K1_CONTEXT_SIZE', '184'),
|
||||||
'USE_ASM_ARM',
|
'USE_ASM_ARM',
|
||||||
'USE_NUM_NONE',
|
|
||||||
'USE_FIELD_INV_BUILTIN',
|
|
||||||
'USE_SCALAR_INV_BUILTIN',
|
|
||||||
'USE_EXTERNAL_ASM',
|
'USE_EXTERNAL_ASM',
|
||||||
'USE_FIELD_10X26',
|
|
||||||
'USE_SCALAR_8X32',
|
|
||||||
'USE_ECMULT_STATIC_PRECOMPUTATION',
|
|
||||||
'USE_EXTERNAL_DEFAULT_CALLBACKS',
|
'USE_EXTERNAL_DEFAULT_CALLBACKS',
|
||||||
('ECMULT_GEN_PREC_BITS', '4'),
|
('ECMULT_GEN_PREC_BITS', '4'),
|
||||||
('ECMULT_WINDOW_SIZE', '8'),
|
('ECMULT_WINDOW_SIZE', '8'),
|
||||||
@ -139,6 +133,8 @@ if FEATURE_FLAGS["SECP256K1_ZKP"]:
|
|||||||
]
|
]
|
||||||
SOURCE_MOD_SECP256K1_ZKP = [
|
SOURCE_MOD_SECP256K1_ZKP = [
|
||||||
'vendor/secp256k1-zkp/src/secp256k1.c',
|
'vendor/secp256k1-zkp/src/secp256k1.c',
|
||||||
|
'vendor/secp256k1-zkp/src/precomputed_ecmult.c',
|
||||||
|
'vendor/secp256k1-zkp/src/precomputed_ecmult_gen.c',
|
||||||
'vendor/secp256k1-zkp/src/asm/field_10x26_arm.s'
|
'vendor/secp256k1-zkp/src/asm/field_10x26_arm.s'
|
||||||
]
|
]
|
||||||
SOURCE_MOD += [
|
SOURCE_MOD += [
|
||||||
@ -679,29 +675,6 @@ if FROZEN:
|
|||||||
|
|
||||||
env.Depends(source_mpyc, qstr_generated)
|
env.Depends(source_mpyc, qstr_generated)
|
||||||
|
|
||||||
#
|
|
||||||
# static secp256-zkp ecmult context
|
|
||||||
#
|
|
||||||
if FEATURE_FLAGS["SECP256K1_ZKP"]:
|
|
||||||
host_env = Environment(ENV=os.environ)
|
|
||||||
host_env.Replace(
|
|
||||||
CC=os.getenv('CC_FOR_BUILD') or 'cc',
|
|
||||||
COPT='-O2',
|
|
||||||
CPPPATH='vendor/secp256k1-zkp',
|
|
||||||
CPPDEFINES=[
|
|
||||||
('ECMULT_GEN_PREC_BITS', '4'),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
gen_context = host_env.Program(
|
|
||||||
target='vendor/secp256k1-zkp/gen_context',
|
|
||||||
source='vendor/secp256k1-zkp/src/gen_context.c',
|
|
||||||
)
|
|
||||||
secp256k1_zkp_ecmult_static_context = host_env.Command(
|
|
||||||
target='vendor/secp256k1-zkp/src/ecmult_static_context.h',
|
|
||||||
source='vendor/secp256k1-zkp/gen_context',
|
|
||||||
action='cd ${SOURCE.dir}; ./gen_context',
|
|
||||||
)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Rust library
|
# Rust library
|
||||||
#
|
#
|
||||||
@ -788,8 +761,6 @@ obj_program.extend(
|
|||||||
' $SOURCE $TARGET', ))
|
' $SOURCE $TARGET', ))
|
||||||
|
|
||||||
env.Depends(obj_program, qstr_generated)
|
env.Depends(obj_program, qstr_generated)
|
||||||
if FEATURE_FLAGS["SECP256K1_ZKP"]:
|
|
||||||
env.Depends(obj_program, secp256k1_zkp_ecmult_static_context)
|
|
||||||
|
|
||||||
program_elf = env.Command(
|
program_elf = env.Command(
|
||||||
target='firmware.elf',
|
target='firmware.elf',
|
||||||
|
@ -120,12 +120,6 @@ if FEATURE_FLAGS["SECP256K1_ZKP"]:
|
|||||||
'USE_SECP256K1_ZKP',
|
'USE_SECP256K1_ZKP',
|
||||||
'USE_SECP256K1_ZKP_ECDSA',
|
'USE_SECP256K1_ZKP_ECDSA',
|
||||||
('SECP256K1_CONTEXT_SIZE', '208'),
|
('SECP256K1_CONTEXT_SIZE', '208'),
|
||||||
'USE_NUM_NONE',
|
|
||||||
'USE_FIELD_INV_BUILTIN',
|
|
||||||
'USE_SCALAR_INV_BUILTIN',
|
|
||||||
'USE_FIELD_10X26',
|
|
||||||
'USE_SCALAR_8X32',
|
|
||||||
'USE_ECMULT_STATIC_PRECOMPUTATION',
|
|
||||||
'USE_EXTERNAL_DEFAULT_CALLBACKS',
|
'USE_EXTERNAL_DEFAULT_CALLBACKS',
|
||||||
('ECMULT_GEN_PREC_BITS', '4'),
|
('ECMULT_GEN_PREC_BITS', '4'),
|
||||||
('ECMULT_WINDOW_SIZE', '8'),
|
('ECMULT_WINDOW_SIZE', '8'),
|
||||||
@ -136,6 +130,8 @@ if FEATURE_FLAGS["SECP256K1_ZKP"]:
|
|||||||
]
|
]
|
||||||
SOURCE_MOD_SECP256K1_ZKP = [
|
SOURCE_MOD_SECP256K1_ZKP = [
|
||||||
'vendor/secp256k1-zkp/src/secp256k1.c',
|
'vendor/secp256k1-zkp/src/secp256k1.c',
|
||||||
|
'vendor/secp256k1-zkp/src/precomputed_ecmult.c',
|
||||||
|
'vendor/secp256k1-zkp/src/precomputed_ecmult_gen.c',
|
||||||
]
|
]
|
||||||
SOURCE_MOD += [
|
SOURCE_MOD += [
|
||||||
'vendor/trezor-crypto/zkp_context.c',
|
'vendor/trezor-crypto/zkp_context.c',
|
||||||
@ -642,29 +638,6 @@ if FROZEN:
|
|||||||
|
|
||||||
env.Depends(source_mpyc, qstr_generated)
|
env.Depends(source_mpyc, qstr_generated)
|
||||||
|
|
||||||
#
|
|
||||||
# static secp256-zkp ecmult context
|
|
||||||
#
|
|
||||||
if FEATURE_FLAGS["SECP256K1_ZKP"]:
|
|
||||||
host_env = Environment(ENV=os.environ)
|
|
||||||
host_env.Replace(
|
|
||||||
CC=os.getenv('CC_FOR_BUILD') or 'cc',
|
|
||||||
COPT='-O2',
|
|
||||||
CPPPATH='vendor/secp256k1-zkp',
|
|
||||||
CPPDEFINES=[
|
|
||||||
('ECMULT_GEN_PREC_BITS', '4'),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
gen_context = host_env.Program(
|
|
||||||
target='vendor/secp256k1-zkp/gen_context',
|
|
||||||
source='vendor/secp256k1-zkp/src/gen_context.c',
|
|
||||||
)
|
|
||||||
secp256k1_zkp_ecmult_static_context = host_env.Command(
|
|
||||||
target='vendor/secp256k1-zkp/src/ecmult_static_context.h',
|
|
||||||
source='vendor/secp256k1-zkp/gen_context',
|
|
||||||
action='cd ${SOURCE.dir}; ./gen_context',
|
|
||||||
)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Rust library
|
# Rust library
|
||||||
#
|
#
|
||||||
@ -730,8 +703,6 @@ if FROZEN:
|
|||||||
obj_program.extend(env.Object(source=source_mpyc))
|
obj_program.extend(env.Object(source=source_mpyc))
|
||||||
|
|
||||||
env.Depends(obj_program, qstr_generated)
|
env.Depends(obj_program, qstr_generated)
|
||||||
if FEATURE_FLAGS["SECP256K1_ZKP"]:
|
|
||||||
env.Depends(obj_program, secp256k1_zkp_ecmult_static_context)
|
|
||||||
|
|
||||||
program = env.Command(
|
program = env.Command(
|
||||||
target='trezor-emu-core',
|
target='trezor-emu-core',
|
||||||
|
@ -45,6 +45,8 @@ SECTIONS {
|
|||||||
.flash2 : ALIGN(512) {
|
.flash2 : ALIGN(512) {
|
||||||
build/firmware/frozen_mpy.o(.rodata*);
|
build/firmware/frozen_mpy.o(.rodata*);
|
||||||
build/firmware/vendor/secp256k1-zkp/src/secp256k1.o(.rodata*);
|
build/firmware/vendor/secp256k1-zkp/src/secp256k1.o(.rodata*);
|
||||||
|
build/firmware/vendor/secp256k1-zkp/src/precomputed_ecmult.o(.rodata*);
|
||||||
|
build/firmware/vendor/secp256k1-zkp/src/precomputed_ecmult_gen.o(.rodata*);
|
||||||
. = ALIGN(512);
|
. = ALIGN(512);
|
||||||
} >FLASH2 AT>FLASH2
|
} >FLASH2 AT>FLASH2
|
||||||
|
|
||||||
|
@ -201,9 +201,8 @@ fn link_core_objects() {
|
|||||||
let crate_path = env::var("CARGO_MANIFEST_DIR").unwrap();
|
let crate_path = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||||
let build_path = format!("{}/../../build/unix", crate_path);
|
let build_path = format!("{}/../../build/unix", crate_path);
|
||||||
|
|
||||||
// List of object filenames to ignore in the `embed` and `vendor` directory
|
// List of object filenames to ignore in the `embed` directory
|
||||||
let embed_blocklist = [OsStr::new("main_main.o")];
|
let embed_blocklist = [OsStr::new("main_main.o")];
|
||||||
let vendor_blocklist = [OsStr::new("gen_context.o")];
|
|
||||||
|
|
||||||
// Collect all objects that the `core` library uses, and link it in. We have to
|
// Collect all objects that the `core` library uses, and link it in. We have to
|
||||||
// make sure to avoid the object with the `_main` symbol, so we don't get any
|
// make sure to avoid the object with the `_main` symbol, so we don't get any
|
||||||
@ -220,13 +219,8 @@ fn link_core_objects() {
|
|||||||
|
|
||||||
for obj in glob::glob(&format!("{}/vendor/**/*.o", build_path)).unwrap() {
|
for obj in glob::glob(&format!("{}/vendor/**/*.o", build_path)).unwrap() {
|
||||||
let obj = obj.unwrap();
|
let obj = obj.unwrap();
|
||||||
if vendor_blocklist.contains(&obj.file_name().unwrap()) {
|
cc.object(obj);
|
||||||
// Ignore.
|
|
||||||
} else {
|
|
||||||
cc.object(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile all the objects into a static library and link it in automatically.
|
// Compile all the objects into a static library and link it in automatically.
|
||||||
cc.compile("core_lib");
|
cc.compile("core_lib");
|
||||||
|
|
||||||
|
@ -63,12 +63,6 @@ CFLAGS += $(OPTFLAGS) \
|
|||||||
-Werror
|
-Werror
|
||||||
|
|
||||||
ZKP_CFLAGS = \
|
ZKP_CFLAGS = \
|
||||||
-DUSE_NUM_NONE \
|
|
||||||
-DUSE_FIELD_INV_BUILTIN \
|
|
||||||
-DUSE_SCALAR_INV_BUILTIN \
|
|
||||||
-DUSE_FIELD_10X26 \
|
|
||||||
-DUSE_SCALAR_8X32 \
|
|
||||||
-DUSE_ECMULT_STATIC_PRECOMPUTATION \
|
|
||||||
-DECMULT_GEN_PREC_BITS=4 \
|
-DECMULT_GEN_PREC_BITS=4 \
|
||||||
-DECMULT_WINDOW_SIZE=8 \
|
-DECMULT_WINDOW_SIZE=8 \
|
||||||
-DENABLE_MODULE_GENERATOR \
|
-DENABLE_MODULE_GENERATOR \
|
||||||
@ -138,6 +132,8 @@ SRCS += cardano.c
|
|||||||
|
|
||||||
OBJS = $(SRCS:.c=.o)
|
OBJS = $(SRCS:.c=.o)
|
||||||
OBJS += secp256k1-zkp.o
|
OBJS += secp256k1-zkp.o
|
||||||
|
OBJS += precomputed_ecmult.o
|
||||||
|
OBJS += precomputed_ecmult_gen.o
|
||||||
|
|
||||||
TESTLIBS = $(shell pkg-config --libs check) -lpthread -lm
|
TESTLIBS = $(shell pkg-config --libs check) -lpthread -lm
|
||||||
TESTSSLLIBS = $(shell pkg-config --libs openssl)
|
TESTSSLLIBS = $(shell pkg-config --libs openssl)
|
||||||
@ -163,8 +159,8 @@ tests/test_speed: tests/test_speed.o $(OBJS)
|
|||||||
tests/test_openssl: tests/test_openssl.o $(OBJS)
|
tests/test_openssl: tests/test_openssl.o $(OBJS)
|
||||||
$(CC) $(CFLAGS) tests/test_openssl.o $(OBJS) $(TESTSSLLIBS) -o tests/test_openssl
|
$(CC) $(CFLAGS) tests/test_openssl.o $(OBJS) $(TESTSSLLIBS) -o tests/test_openssl
|
||||||
|
|
||||||
tests/libtrezor-crypto.so: $(SRCS) secp256k1-zkp.o
|
tests/libtrezor-crypto.so: $(SRCS) secp256k1-zkp.o precomputed_ecmult.o precomputed_ecmult_gen.o
|
||||||
$(CC) $(CFLAGS) -DAES_128 -DAES_192 -fPIC -shared $(SRCS) secp256k1-zkp.o -o tests/libtrezor-crypto.so
|
$(CC) $(CFLAGS) -DAES_128 -DAES_192 -fPIC -shared $(SRCS) secp256k1-zkp.o precomputed_ecmult.o precomputed_ecmult_gen.o -o tests/libtrezor-crypto.so
|
||||||
|
|
||||||
tools: tools/xpubaddrgen tools/mktable tools/bip39bruteforce
|
tools: tools/xpubaddrgen tools/mktable tools/bip39bruteforce
|
||||||
|
|
||||||
@ -180,11 +176,13 @@ tools/bip39bruteforce: tools/bip39bruteforce.o $(OBJS)
|
|||||||
fuzzer: fuzzer/fuzzer.o $(OBJS)
|
fuzzer: fuzzer/fuzzer.o $(OBJS)
|
||||||
$(CC) $(CFLAGS) fuzzer/fuzzer.o $(OBJS) -o fuzzer/fuzzer
|
$(CC) $(CFLAGS) fuzzer/fuzzer.o $(OBJS) -o fuzzer/fuzzer
|
||||||
|
|
||||||
$(ZKP_PATH)/src/ecmult_static_context.h: $(ZKP_PATH)/src/gen_context.c
|
precomputed_ecmult.o:
|
||||||
$(CC) $(ZKP_CFLAGS) $(ZKP_PATH)/src/gen_context.c -o $(ZKP_PATH)/gen_context
|
$(CC) $(CFLAGS) -Wno-unused-function $(ZKP_CFLAGS) -fPIC -c $(ZKP_PATH)/src/precomputed_ecmult.c -o precomputed_ecmult.o
|
||||||
cd $(ZKP_PATH) && ./gen_context
|
|
||||||
|
|
||||||
secp256k1-zkp.o: $(ZKP_PATH)/src/ecmult_static_context.h
|
precomputed_ecmult_gen.o:
|
||||||
|
$(CC) $(CFLAGS) -Wno-unused-function $(ZKP_CFLAGS) -fPIC -c $(ZKP_PATH)/src/precomputed_ecmult_gen.c -o precomputed_ecmult_gen.o
|
||||||
|
|
||||||
|
secp256k1-zkp.o:
|
||||||
$(CC) $(CFLAGS) -Wno-unused-function $(ZKP_CFLAGS) -fPIC -I$(ZKP_PATH) -I$(ZKP_PATH)/src -c $(ZKP_PATH)/src/secp256k1.c -o secp256k1-zkp.o
|
$(CC) $(CFLAGS) -Wno-unused-function $(ZKP_CFLAGS) -fPIC -I$(ZKP_PATH) -I$(ZKP_PATH)/src -c $(ZKP_PATH)/src/secp256k1.c -o secp256k1-zkp.o
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@ -192,9 +190,7 @@ clean:
|
|||||||
rm -f tests/*.o tests/test_check tests/test_speed tests/test_openssl tests/libtrezor-crypto.so tests/aestst
|
rm -f tests/*.o tests/test_check tests/test_speed tests/test_openssl tests/libtrezor-crypto.so tests/aestst
|
||||||
rm -f tools/*.o tools/xpubaddrgen tools/mktable tools/bip39bruteforce
|
rm -f tools/*.o tools/xpubaddrgen tools/mktable tools/bip39bruteforce
|
||||||
rm -f fuzzer/*.o fuzzer/fuzzer
|
rm -f fuzzer/*.o fuzzer/fuzzer
|
||||||
rm -f secp256k1-zkp.o
|
rm -f secp256k1-zkp.o precomputed_ecmult.o precomputed_ecmult_gen.o
|
||||||
rm -f $(ZKP_PATH)/gen_context
|
|
||||||
rm -f $(ZKP_PATH)/src/ecmult_static_context.h
|
|
||||||
|
|
||||||
clean-fuzzer: clean
|
clean-fuzzer: clean
|
||||||
rm -f crash-* fuzz-*.log slow-unit-* timeout-*
|
rm -f crash-* fuzz-*.log slow-unit-* timeout-*
|
||||||
|
@ -140,8 +140,8 @@ int zkp_bip340_sign_digest(const uint8_t *private_key_bytes,
|
|||||||
if (!auxiliary_data) {
|
if (!auxiliary_data) {
|
||||||
auxiliary_data = zero;
|
auxiliary_data = zero;
|
||||||
}
|
}
|
||||||
if (secp256k1_schnorrsig_sign(context_writable, signature_bytes, digest,
|
if (secp256k1_schnorrsig_sign32(context_writable, signature_bytes, digest,
|
||||||
&keypair, auxiliary_data) != 1) {
|
&keypair, auxiliary_data) != 1) {
|
||||||
result = -1;
|
result = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,12 +203,15 @@ $(NAME).elf: $(OBJS) $(LDSCRIPT) $(LIBDEPS)
|
|||||||
@printf " LD $@\n"
|
@printf " LD $@\n"
|
||||||
$(Q)$(LD) -o $(NAME).elf $(OBJS) $(LDLIBS) $(LDFLAGS)
|
$(Q)$(LD) -o $(NAME).elf $(OBJS) $(LDLIBS) $(LDFLAGS)
|
||||||
|
|
||||||
$(ZKP_PATH)/src/ecmult_static_context.h: $(ZKP_PATH)/src/gen_context.c
|
precomputed_ecmult.o:
|
||||||
@printf " GEN $@\n"
|
@printf " CC $@\n"
|
||||||
$(Q)$(CC_FOR_BUILD) $(ZKP_CFLAGS) $(ZKP_PATH)/src/gen_context.c -o $(ZKP_PATH)/gen_context
|
$(Q)$(CC) $(CFLAGS) -Wno-unused-function $(ZKP_CFLAGS) -c $(ZKP_PATH)/src/precomputed_ecmult.c -o precomputed_ecmult.o
|
||||||
$(Q)cd $(ZKP_PATH) && ./gen_context
|
|
||||||
|
|
||||||
secp256k1-zkp.o: $(ZKP_PATH)/src/ecmult_static_context.h
|
precomputed_ecmult_gen.o:
|
||||||
|
@printf " CC $@\n"
|
||||||
|
$(Q)$(CC) $(CFLAGS) -Wno-unused-function $(ZKP_CFLAGS) -c $(ZKP_PATH)/src/precomputed_ecmult_gen.c -o precomputed_ecmult_gen.o
|
||||||
|
|
||||||
|
secp256k1-zkp.o:
|
||||||
@printf " CC $@\n"
|
@printf " CC $@\n"
|
||||||
$(Q)$(CC) $(CFLAGS) -Wno-unused-function $(ZKP_CFLAGS) -I$(ZKP_PATH) -I$(ZKP_PATH)/src -c $(ZKP_PATH)/src/secp256k1.c -o secp256k1-zkp.o
|
$(Q)$(CC) $(CFLAGS) -Wno-unused-function $(ZKP_CFLAGS) -I$(ZKP_PATH) -I$(ZKP_PATH)/src -c $(ZKP_PATH)/src/secp256k1.c -o secp256k1-zkp.o
|
||||||
|
|
||||||
|
1
legacy/firmware/.changelog.d/2261.changed
Normal file
1
legacy/firmware/.changelog.d/2261.changed
Normal file
@ -0,0 +1 @@
|
|||||||
|
Updated secp256k1-zkp.
|
@ -16,13 +16,7 @@ OBJS += field_10x26_arm.o
|
|||||||
endif
|
endif
|
||||||
ZKP_CFLAGS = \
|
ZKP_CFLAGS = \
|
||||||
-DUSE_ASM_ARM \
|
-DUSE_ASM_ARM \
|
||||||
-DUSE_NUM_NONE \
|
|
||||||
-DUSE_FIELD_INV_BUILTIN \
|
|
||||||
-DUSE_SCALAR_INV_BUILTIN \
|
|
||||||
-DUSE_EXTERNAL_ASM \
|
-DUSE_EXTERNAL_ASM \
|
||||||
-DUSE_FIELD_10X26 \
|
|
||||||
-DUSE_SCALAR_8X32 \
|
|
||||||
-DUSE_ECMULT_STATIC_PRECOMPUTATION \
|
|
||||||
-DUSE_EXTERNAL_DEFAULT_CALLBACKS \
|
-DUSE_EXTERNAL_DEFAULT_CALLBACKS \
|
||||||
-DECMULT_GEN_PREC_BITS=4 \
|
-DECMULT_GEN_PREC_BITS=4 \
|
||||||
-DECMULT_WINDOW_SIZE=8 \
|
-DECMULT_WINDOW_SIZE=8 \
|
||||||
@ -32,6 +26,8 @@ ZKP_CFLAGS = \
|
|||||||
-DENABLE_MODULE_EXTRAKEYS
|
-DENABLE_MODULE_EXTRAKEYS
|
||||||
|
|
||||||
OBJS += secp256k1-zkp.o
|
OBJS += secp256k1-zkp.o
|
||||||
|
OBJS += precomputed_ecmult.o
|
||||||
|
OBJS += precomputed_ecmult_gen.o
|
||||||
OBJS += ../vendor/trezor-crypto/zkp_bip340.o
|
OBJS += ../vendor/trezor-crypto/zkp_bip340.o
|
||||||
OBJS += ../vendor/trezor-crypto/zkp_context.o
|
OBJS += ../vendor/trezor-crypto/zkp_context.o
|
||||||
OBJS += ../vendor/trezor-crypto/zkp_ecdsa.o
|
OBJS += ../vendor/trezor-crypto/zkp_ecdsa.o
|
||||||
|
2
vendor/secp256k1-zkp
vendored
2
vendor/secp256k1-zkp
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 6b8733577e4a8e1a4f77aaa48691f188b0c42f5c
|
Subproject commit 7a30cb0c9d99ab195c461a6fb4e654cd4ef19a8d
|
Loading…
Reference in New Issue
Block a user